数据库问题:将简单关系表更改为非关系表?

时间:2009-06-02 09:58:56

标签: mysql database database-design rdbms non-relational-database

我有一个在MySQL数据库上运行的Web应用程序(在开发中)。我正在考虑将我的应用程序迁移到Google App Engine,并希望更好地理解我的简单关系数据库模型如何转换为非关系数据库方法。

我是一名长期的关系数据库人员,我没有基于列的数据库(如BigTable)的经验。为了防止谷歌也支持关系数据库的小型部署,我想说明我的问题是一般的,而不是谷歌特有的 - 我想了解如何在非关系数据库中表示简单的关系模型。

我的数据库(简化)如下:

Items Table
------------

ItemID  ItemName  ItemPriority
1       "Car"     7
2       "Table"   2
3       "Desk"    7

ItemProperties Table
---------------------

ItemID  Property        Importance 
1       "Blue"          1
1       "Four Wheels"   2
1       "Sedan"         0
2       "Rectangular"   1
2       "One Leg"       1

我有很多项目,每个项目都有名称和ID。每个项目都有多个属性,每个属性都有几个参数(我只列出了每个属性的名称和“重要性”,但还有更多)。我有数千万件物品,每件都有数百种物品。

使用场景:我收到一个ItemName作为输入,在items表中查找其ID,并按该id获取所有属性。然后,我对属性列表(在内存中)执行一些分析,并返回结果。

90%的工作是基于参数进行查找,如果我理解正确的话,这是非关系数据库的痛点。

推荐的方法是什么?

4 个答案:

答案 0 :(得分:1)

从一直使用非关系数据库的人开始,你的两个表应该很容易转换为非关系数据库。

取两张桌子并将它们变成一个对象。

档案:  - ID  - 名称   - 属性      - prop1      - prop2

将整个内容存储在数据存储列(Big-Table),文档(CouchDB)或其他任何使用的内容中。

您可以按任何ID,名称或属性查找项目。没有连接是非关系dbs的一个更大的痛点。参数查找并不是一个痛点,除非我不明白你的意思。您可能不得不进行多次查找,但大部分时间都不是问题,并且它比rdbms更好地扩展。

在您的示例中,我实际上认为非关系模型更简单,更容易实现和理解。

每个非关系数据存储都有不同的约定和约束,但在一般意义上很难给出指导。例如,CouchDB可以使用它的视图在对象的任何部分上创建索引。使用BigTable,您可能必须存储非规范化数据的多个副本才能获得快速索引查找。当您决定如何存储数据时,其他人将需要考虑不同的事情。一旦离开SQL世界,就会有很多差异化。

答案 1 :(得分:0)

GQL不支持联接。您可以通过两种方式解决此问题:

  • 自己加入

只需获取Item,检查其ItemID,然后使用该ItemID查询ItemProperties。您的表格看起来与您指定的完全相同。当然,这是两个查询,但这两个查询很简单。

  • 使用Expando模型

在Expando模型中,您可以在运行时创建新字段。它们不会被编入索引,所以如果你想搜索它们可能会更慢,但只需获取它们就可以了。您也可以使用像ListProperty这样的复杂类型。通过这种灵活性,您可以想出一种方法将ItemProperties表中的所有内容放入Items表中,并保存自己的查询。要有创意。

答案 2 :(得分:0)

我有一个非常相似的数据库结构(我们的“records”和“recordEntries”表镜像你的“items”和“itemProperties”),我正在考虑类似的迁移到非关系数据库。我们可能会去CouchDB或memcachedb或类似的东西,而不是谷歌。

和我一样,我没有使用非关系数据库的经验(我的开发人员也没有)。但是,我们已经提出了几个想法。我们目前的想法是(使用您的架构):

  • 首先:将每个项目及其项目属性折叠为一个带有字段的对象(实际上是一个XML文档),并将其填入由标识符键入的数据库中。每次检索项目时,您都会获得所有itemProperties。

请注意,我们的差异是我们将数据库外部的索引(使用Solr)编入索引,因此不需要使用“name”属性对数据库本身进行查找,因此YMMV。

  • 第二:我们正在列出我们正在进行的所有“关系”操作,而上述模型无法支持这些操作。这包括一些“分组”操作,我们根据项目表中的特殊字段查询项目,以及我们尝试检测最近修改过的所有项目的查询(之前通过查询日期列中的查询完成)项目表)。我们正在为每种情况发明替代实现(幸运的是,只有少数几种情况)。

如果这太难了,我们将尝试与另一个模型相同的练习。幸运的是,我们有时间计划。

我们的一个关键点是我们使用Solr在外部进行所有索引,因此(例如)我们不需要对itemProperties值中的值进行数据库查找,也不需要在名称上执行查找项目表。

无论如何,这可能没什么帮助,但我会热切地想看看更有经验的人可以提出哪种解决方案。

PS:我推断你的属性表必须有数十亿行。您运行MySQL服务器的确切数量和硬件数量是多少?您是否在使用MySQL时遇到了可扩展性问题?

答案 3 :(得分:0)

你需要将它弄平,我认为AppEngine允许像

这样的结构

ID = 1,ItemName = Car,ItemPriority = 7,Property =(Blue,1),Property =(Four Wheels,2),Property =(Sedan,0) ID = 2,ItemName = Table,ItemPriority = 2,Property =(Rectangular,1),Property =(One Leg,1) ID = 3,ItemName = Desk,ItemPriority = 7

请注意,相同的“字段”可以包含多个值,并且您可以在其中使用多个项目。

您的样本数据在一个表中将是3行。