如何使用分布式数据库做传统开发工作

您好

我提一个问题:
根据分布式数据库的技术原理,在建表的时候,需要指定分区键,有业务相关的数据表都需要带有同样的字段,才能充分发挥数据库的性能,比如要制作一个电子商务管理系统,可以按照用户登录账号作为分区键,来保存用户购物车、用户收藏夹、用户订单、用户订单的物流,每个表都带有 user_id 字段,这样在表连接的时候,就不会出现跨分区跨服务器查询的问题,然而对于没有明确分区键的业务怎么去使用分布式数据库呢?比如一个进销存系统,要管理物料、客户、供应商、出入库数据、现有量、采购合同、采购订单、销售合同、销售订单、预收款、应收款、销售发票、实际收款、预付款、应付款、应付发票、实际付款、员工报销单、无形资产、固定资产,并且要在同一个系统里面实现不同核算单位的多账套数据屏蔽和报表的合并查询、公司间交易的采购转销售、公司间交易的应收应付对冲,在这种情况下,数据表比较多并且关联关系没有简单明确的分区键,应该怎么去做才能顺利的基于分布式数据库来搭建系统呢?举例来说,经常见到这种复杂关联:
举例1:
SELECT *
FROM Mtl_Parameters Ship_From_Org,
Hz_Cust_Site_Uses_All Ship_Su,
Hz_Party_Sites Ship_Ps,
Hz_Locations Ship_Loc,
Hz_Cust_Acct_Sites_All Ship_Cas,
Hz_Cust_Site_Uses_All Bill_Su,
Hz_Party_Sites Bill_Ps,
Hz_Locations Bill_Loc,
Hz_Cust_Acct_Sites_All Bill_Cas,
Hz_Parties Party,
Hz_Cust_Accounts Cust_Acct,
Ra_Terms_Tl Term,
Oe_Order_Headers h,
Hz_Cust_Account_Roles Sold_Roles,
Hz_Parties Sold_Party,
Hz_Cust_Accounts Sold_Acct,
Hz_Relationships Sold_Rel,
Ar_Lookups Sold_Arl,
Hz_Cust_Account_Roles Ship_Roles,
Hz_Parties Ship_Party,
Hz_Relationships Ship_Rel,
Hz_Cust_Accounts Ship_Acct,
Ar_Lookups Ship_Arl,
Hz_Cust_Account_Roles Invoice_Roles,
Hz_Parties Invoice_Party,
Hz_Relationships Invoice_Rel,
Hz_Cust_Accounts Invoice_Acct,
Ar_Lookups Invoice_Arl,
Fnd_Currencies Fndcur,
Oe_Transaction_Types_Tl Ot,
Qp_List_Headers_Tl Pl,
Ra_Rules Invrule,
Ra_Rules Accrule
WHERE h.Order_Type_Id = Ot.Transaction_Type_Id
AND Ot.Language = Userenv(‘LANG’)
AND h.Price_List_Id = Pl.List_Header_Id(+)
AND Pl.Language(+) = Userenv(‘LANG’)
AND h.Invoicing_Rule_Id = Invrule.Rule_Id(+)
AND h.Accounting_Rule_Id = Accrule.Rule_Id(+)
AND h.Payment_Term_Id = Term.Term_Id(+)
AND Term.Language(+) = Userenv(‘LANG’)
AND h.Transactional_Curr_Code = Fndcur.Currency_Code
AND h.Sold_To_Org_Id = Cust_Acct.Cust_Account_Id(+)
AND Cust_Acct.Party_Id = Party.Party_Id(+)
AND h.Ship_From_Org_Id = Ship_From_Org.Organization_Id(+)
AND h.Ship_To_Org_Id = Ship_Su.Site_Use_Id(+)
AND Ship_Su.Cust_Acct_Site_Id = Ship_Cas.Cust_Acct_Site_Id(+)
AND Ship_Cas.Party_Site_Id = Ship_Ps.Party_Site_Id(+)
AND Ship_Loc.Location_Id(+) = Ship_Ps.Location_Id
AND h.Invoice_To_Org_Id = Bill_Su.Site_Use_Id(+)
AND Bill_Su.Cust_Acct_Site_Id = Bill_Cas.Cust_Acct_Site_Id(+)
AND Bill_Cas.Party_Site_Id = Bill_Ps.Party_Site_Id(+)
AND Bill_Loc.Location_Id(+) = Bill_Ps.Location_Id
AND h.Sold_To_Contact_Id = Sold_Roles.Cust_Account_Role_Id(+)
AND Sold_Roles.Party_Id = Sold_Rel.Party_Id(+)
AND Sold_Roles.Role_Type(+) = ‘CONTACT’
AND Sold_Roles.Cust_Account_Id = Sold_Acct.Cust_Account_Id(+)
AND Nvl(Sold_Rel.Object_Id, -1) = Nvl(Sold_Acct.Party_Id, -1)
AND Sold_Rel.Subject_Id = Sold_Party.Party_Id(+)
AND Sold_Arl.Lookup_Type(+) = ‘CONTACT_TITLE’
AND Sold_Arl.Lookup_Code(+) = Sold_Party.Person_Pre_Name_Adjunct
AND h.Ship_To_Contact_Id = Ship_Roles.Cust_Account_Role_Id(+)
AND Ship_Roles.Party_Id = Ship_Rel.Party_Id(+)
AND Ship_Roles.Role_Type(+) = ‘CONTACT’
AND Ship_Roles.Cust_Account_Id = Ship_Acct.Cust_Account_Id(+)
AND Nvl(Ship_Rel.Object_Id, -1) = Nvl(Ship_Acct.Party_Id, -1)
AND Ship_Rel.Subject_Id = Ship_Party.Party_Id(+)
AND Ship_Arl.Lookup_Type(+) = ‘CONTACT_TITLE’
AND Ship_Arl.Lookup_Code(+) = Ship_Party.Person_Pre_Name_Adjunct
AND h.Invoice_To_Contact_Id = Invoice_Roles.Cust_Account_Role_Id(+)
AND Invoice_Roles.Party_Id = Invoice_Rel.Party_Id(+)
AND Invoice_Roles.Role_Type(+) = ‘CONTACT’
AND Invoice_Roles.Cust_Account_Id = Invoice_Acct.Cust_Account_Id(+)
AND Nvl(Invoice_Rel.Object_Id, -1) = Nvl(Invoice_Acct.Party_Id, -1)
AND Invoice_Rel.Subject_Id = Invoice_Party.Party_Id(+)
AND Invoice_Arl.Lookup_Type(+) = ‘CONTACT_TITLE’
AND Invoice_Arl.Lookup_Code(+) = Invoice_Party.Person_Pre_Name_Adjunct
举例2:
SELECT *
FROM Ap_Invoices_All Ai,
Ap_Batches_All Ab,
Ap_Lookup_Codes Alc1,
Ap_Lookup_Codes Alc2,
Ap_Lookup_Codes Alc4,
Ap_Other_Period_Types Aopt,
Ap_Recurring_Payments_All Arp,
Ap_Terms At,
Ap_System_Parameters Asp,
Fnd_Currencies Fc,
Fnd_Document_Sequences Fds,
Fnd_Doc_Sequence_Categories Fdsc,
Gl_Sets_Of_Books Gsob,
Gl_Daily_Conversion_Types Gdct,
Hr_Organization_Units Hou,
Po_Vendors Pv,
Po_Vendor_Sites_All Pvs,
Ap_Awt_Groups Awt,
Ap_Awt_Groups Awt1,
Pa_Projects_All Pap,
Pa_Tasks Pat,
Zx_Fc_Business_Categories_v Zbc,
Fnd_Territories_Tl Fnd,
Ap_Distribution_Sets Dset,
Po_Headers Ph,
Iby_Payment_Methods_Vl Iby1,
Iby_Payment_Reasons_Vl Iby2,
Fnd_Lookups Iby3,
Iby_Delivery_Channels_Vl Iby4,
Fnd_Lookups Iby5,
Iby_Ext_Bank_Accounts Ibybnk,
Hz_Parties Hp
WHERE Ai.Batch_Id = Ab.Batch_Id(+)
AND Ai.Recurring_Payment_Id = Arp.Recurring_Payment_Id(+)
AND Arp.Rec_Pay_Period_Type = Aopt.Period_Type(+)
AND Aopt.Module(+) = ‘RECURRING PAYMENT’
AND Ai.Terms_Id = At.Term_Id(+)
AND Alc1.Lookup_Type(+) = ‘INVOICE TYPE’
AND Alc1.Lookup_Code(+) = Ai.Invoice_Type_Lookup_Code
AND Alc2.Lookup_Type(+) = ‘INVOICE PAYMENT STATUS’
AND Alc2.Lookup_Code(+) = Ai.Payment_Status_Flag
AND Alc4.Lookup_Type(+) = ‘AP_WFAPPROVAL_STATUS’
AND Alc4.Lookup_Code(+) = Ai.Wfapproval_Status
AND Zbc.Classification_Code(+) = Ai.Trx_Business_Category
AND Zbc.Application_Id(+) = 200
AND Zbc.Entity_Code(+) = ‘AP_INVOICES’
AND Ai.Exchange_Rate_Type = Gdct.Conversion_Type(+)
AND Ai.Doc_Sequence_Id = Fds.Doc_Sequence_Id(+)
AND Fdsc.Code(+) = Ai.Doc_Category_Code
AND Fdsc.Application_Id(+) = 200
AND Ai.Set_Of_Books_Id = Gsob.Set_Of_Books_Id
AND Ai.Expenditure_Organization_Id = Hou.Organization_Id(+)
AND Ai.Vendor_Site_Id = Pvs.Vendor_Site_Id(+)
AND Ai.Project_Id = Pap.Project_Id(+)
AND Ai.Task_Id = Pat.Task_Id(+)
AND Ai.Awt_Group_Id = Awt.Group_Id(+)
AND Ai.Pay_Awt_Group_Id = Awt1.Group_Id(+)
AND Ai.Invoice_Currency_Code = Fc.Currency_Code(+)
AND Ai.Org_Id = Asp.Org_Id
AND Fnd.Territory_Code(+) = Ai.Taxation_Country
AND (Ai.Taxation_Country IS NULL OR Fnd.Language = Userenv(‘LANG’))
AND Ai.Distribution_Set_Id = Dset.Distribution_Set_Id(+)
AND Ai.Quick_Po_Header_Id = Ph.Po_Header_Id(+)
AND Ai.Payment_Method_Code = Iby1.Payment_Method_Code(+)
AND Ai.Payment_Reason_Code = Iby2.Payment_Reason_Code(+)
AND Ai.Bank_Charge_Bearer = Iby3.Lookup_Code(+)
AND Iby3.Lookup_Type(+) = ‘IBY_BANK_CHARGE_BEARER’
AND Ai.Delivery_Channel_Code = Iby4.Delivery_Channel_Code(+)
AND Ai.Settlement_Priority = Iby5.Lookup_Code(+)
AND Iby5.Lookup_Type(+) = ‘IBY_SETTLEMENT_PRIORITY’
AND Ibybnk.Ext_Bank_Account_Id(+) = Ai.External_Bank_Account_Id
AND Ai.Party_Id = Hp.Party_Id
AND Pv.Vendor_Id(+) = Ai.Vendor_Id
AND Ai.Approval_Ready_Flag <> ‘S’;

这些查询很复杂,但是并不是为了复杂而复杂,是由于要实现功能只能写成这样,并且上面的查询已经做了简化,表关联中用到了一些视图,如果都用表,会更复杂。

谢谢!

可以看看 table group 能不能解决你的问题

这个能解决吗?

这种是要根据实际业务场景的,并没有很统一的答案,甚至在不同的分布式数据库系统上根据不同的实现,最优的分区方式也不同,你应该给出一个很具体的场景

业务场景就是:管理物料、客户、供应商、出入库数据、现有量、采购合同、采购订单、销售合同、销售订单、预收款、应收款、销售发票、实际收款、预付款、应付款、应付发票、实际付款、员工报销单、无形资产、固定资产,并且要在同一个系统里面实现不同核算单位的多账套数据屏蔽和报表的合并查询、公司间交易的采购转销售、公司间交易的应收应付对冲。

有两个疑问哈:1、我们这个多表关联查询是经常性的语句还是偶发的? 2、最终的结果是取某些字段还是都要,即 select * ?