具有重复数据的数据库表设计

时间:2017-07-15 13:28:07

标签: json firebase firebase-realtime-database nosql

在尝试设计我的firebase数据库结构时遇到了一些问题。基本上,1个帐户可以有很多收据,1个收据可以有很多项目。这是JSON:

receipts {
    accountID1 : {
        receiptID1 : {
            date : "07/07/2017"
            store : {
                storeName : "store1"
                storeAddr : "addr1"
            }
            currency : {
                currencyName : "currency1"
                currentcySymbol : "$"
            }
            totalAmount : "50.00"
            items : {
                itemID1 : true,
                itemID2 : true,
            }
        }
        receiptID2 : {
            date : "08/07/2017"
                store : {
                    storeName : "store1"
                    storeAddr : "addr1"
                }
                currency : {
                    currencyName : "currency1"
                    currentcySymbol : "$"
                }
                totalAmount : "20.00"
                items : {
                    itemID3 : true,
                    itemID4 : true,
                }
        }
    }
},
items {
        itemID1 : {
            type : "food"
            name : "snack"
            unitprice : "10.00"
            quantity : "2"
        }
        itemID2 : { 
            type : "entertainment"
            name : "gaming equipment"
            unitprice : "150.00"
            quantity : "1"
        }
        itemID3 : { 
            type : "food"
            name : "fruit juice"
            unitprice : "4.00"
            quantity : "1"
        } 
        itemID4 : {
            type : "entertainment"
            name : "gaming equipment"
            unitprice : "150.00"
            quantity : "1"
        }
},
itemIDsByType {
    food : {
        itemID1 : true,
        itemID3 : true,
    }
    entertainment: {
        itemID2 : true,
        itemID4 : true,
    }
}

我意识到items孩子下面存在重复问题。例如,帐户A在收据1中购买物品A.然后,帐户A在收据中再次购买相同的物品2.在receipt的孩子下,是的,不会造成任何干扰。

但是,通过查看items孩子,特别是itemID2itemID4,他们是相同的项目,但属于不同的收据。这两个记录是重复的,让我们说一大堆数据,我认为这个设计可能会导致问题。

有关如何重组数据库设计以消除上述重复问题的任何想法?

我实际上已经推出了另一种设计,但却不那么扁平了:

receipts {
    accountID1 : {
        receiptID1 : {
            date : "07/07/2017"
            merchantName : "NTUC"
            branch : {
                branchName : "Marsiling"
                branchAddress : "Blk 167, Marsiling"
            }
            currency : {
                currencyName : "currency1"
                currencySymbol : "$"
            }
            totalAmount : "50.00"
        }

        receiptID2 : {
            date : "08/07/2017"
            merchantName : "NTUC"
            branch : {
                branchName : "Marsiling"
                branchAddress : "Blk 167, Marsiling"
            }
            currency : {
                currencyName : "currency1"
                currencySymbol : "$"
            }
            totalAmount : "20.00"
        }
    }
},

itemLists {
    receiptID1 : {
        items : {
            itemID1 : {
                type : "food"
                name : "snack"
                unitprice : "10.00"
                quantity : "2"
            }

            itemID2 : { 
                type : "entertainment"
                name : "gaming equipment"
                unitprice : "150.00"
                quantity : "1"
            }

            itemID3 : { 
                type : "food"
                name : "fruit juice"
                unitprice : "4.00"
                quantity : "1"
            } 
        }
    }

    receiptID2 : { 
        items : {
            itemID4 : {
                type : "entertainment"
                name : "gaming equipment"
                unitprice : "150.00"
                quantity : "1"
            }
        }
    }
},
itemIDsByType {
        food : {
            itemID1 : true,
            itemID3 : true,
        }
        entertainment: {
            itemID2 : true,
            itemID4 : true,
        }
},
merchants {
    merchantID1 : {
        merchantName : "NTUC"
        branches : {
            branchID1 : {
                branchName : "Marsiling"
                branchAddress : "Blk 167, Marsiling"
            }
            branchID2 : {
                branchName : "Woodlands"
                branchAddress : "Blk 161, Woodlands"
            }
        }
    }
}

对于此设计,每个项目都分组在每个receiptID下,这样可以消除上面提到的重复问题。但我发现它不那么扁平,我试图在扁平化设计与重复数据之间进行调整,或者在没有重复数据的情况下进行较少扁平化设计。哪一个对大量数据更好?

1 个答案:

答案 0 :(得分:1)

让我们从主项目列表开始。此列表是可供出售的所有商品。

item_0
  name: "burger"
item_1
  name: "taco"
item_2
  name: "hot dog"
item_3
  name: "fries"
item_4
  name: "refried beans"

然后收据节点存储有关收据,日期,时间,客户名称等的信息。请注意,没有直接需要的项目参考,但可以为方便起见添加。

receipt_0
   customer: "Frank"
   timestamp: 170716093623
receipt_1
   customer: "Bill"
   timestamp: 170716094515

最后是每张收据上的项目详情。

receipt_items:
   -Y89jasjdiasd:
      item_id: item_0
      price: 5.00
      qty: 1
      receipt: receipt_0
   -YHJis9asdasd:
      item_id: item_3
      price: 1.50
      qty: 1
      receipt: receipt_0
   -Yn9kasdpaosd:
      item_id: item_1
      price: 2.00
      qty: 3
      receipt: receipt_1
   -Yllois9040ka:
      item_id: item_4
      price: 1.50
      qty: 1
      receipt: receipt_1

正如你所看到的,弗兰克在receipt_0上得到一个汉堡和薯条,比尔在收据上得到了3个炸玉米饼(!)和一个豆泥的一面

使用此结构,您可以获取每个收据,客户,日期等的详细信息。或者在receipt_items节点查询receipt_id并获取其上的项目的详细信息 - 项目,价格,数量等。

您还可以在receipt_items节点查询特定项目;然后总结一下最流行的数量或平均售价。

这消除了重复的项目和数据,并提供了可查询的非规范化结构。

如上所述,您可以为每个收据添加子节点以存储receipt_items,但由于receipt_items是可查询的,因此可能不需要。它可以用来订购收据上的物品..

注意:receipt_items中的子节点键是使用childByAutoId创建的。