【问题标题】:Database Question: Change Simple Relational Tables to Non-Relational?数据库问题:将简单的关系表更改为非关系表?
【发布时间】:2010-10-30 15:20:38
【问题描述】:

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

我长期从事关系数据库工作,但对 BigTable 等基于列的数据库没有经验。以防万一 Google 还支持关系数据库的小型部署,我想说明我的问题是一般性的,而不是针对 Google 的 - 我想了解如何在非关系数据库中表示简单的关系模型。

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

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% 的工作是基于参数的查找,这(如果我理解正确的话)是非关系数据库的痛点。

推荐的方法是什么?

【问题讨论】:

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


    【解决方案1】:

    从已经使用非关系数据库一段时间的人那里得到你的两个表应该很容易转换为非关系数据库。

    把两张桌子变成一个物体。

    项目: - ID - 姓名 - 特性 - 道具1 - 道具2

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

    您可以通过任何 ID、名称或属性来查找项目。没有连接是非关系数据库的最大痛点之一。除非我不理解您的意思,否则参数查找并不是真正的痛点。您可能需要进行多次查找,但大多数时候这不是问题,而且它的扩展性比 rdbms 更好。

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

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

    【讨论】:

      【解决方案2】:

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

      • 自己加入

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

      • 使用 Expando 模型

      在 Expando 模型中,您可以在运行时创建新字段。它们不会被索引,因此如果您想搜索它们可能会更慢,但只需获取它们就可以了。您也可以使用复杂类型,例如 ListProperty。有了这种灵活性,您也许可以想办法将 ItemProperties 表中的所有内容都放入 Items 表中,并为自己节省一个查询。要有创意。

      【讨论】:

      • 关于您的第一个选项,第一个(主要是第二个)查询不会非常慢吗?
      【解决方案3】:

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

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

      • 首先:将每个项目及其项目属性折叠成一个带有字段的对象(本质上是一个 XML 文档),然后将其填充到以标识符为关键字的数据库中。每次您检索一个项目时,您也会返回所有 itemProperties。

      请注意,我们的不同之处在于我们在数据库之外(使用 Solr)为我们的内容编制索引,因此不需要使用“名称”属性对数据库本身进行查找,因此是 YMMV。

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

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

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

      无论如何,这可能没什么帮助,但我很想看看更有经验的人能想出什么样的解决方案。

      PS:我推断您的属性表必须有数十亿行。到底有多少,你在什么硬件上运行 MySQL 服务器?您是否还在使用 MySQL 时遇到可扩展性问题?

      【讨论】:

      • 感谢您的详细回答。我还没有数十亿的财产,因为系统还没有上线。 MySQL 规模是我通过迁移到谷歌或其他替代品来提前避免的事情之一。
      【解决方案4】:

      你需要把它全部展平,我认为 AppEngine 允许像这样的结构

      ID=1,ItemName=汽车,ItemPriority=7,Property=(蓝色,1),Property=(四轮,2),Property=(轿车,0) ID=2, ItemName=Table, ItemPriority=2, Property=(Rectangular,1),Property=(One Leg,1) ID=3,ItemName=Desk,ItemPriority=7

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

      您的示例数据将是一个表中的 3 行。

      【讨论】:

        猜你喜欢
        • 2011-02-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-23
        • 1970-01-01
        • 2010-12-20
        • 1970-01-01
        相关资源
        最近更新 更多