创建了Object-Relational-Mappers,以帮助应用程序(以对象的方式思考)以更加应用程序友好的方式处理存储的数据,就像每个其他类/对象一样。
但是,我从未见过NoSQL“Key / Value”存储系统的OKM(Object-Key / Value-Mapper)。这似乎很奇怪,因为需要更多的东西,因为更多的价值关系必须硬编码到应用程序中而不是常规的单个SQL表行对象。
four requests:
user:id
user:id:name
user:id:email
user:id:created
vs one request:
user = [id => ..., name => ..., email => ...]
另外,你必须跟踪“列表”(发布has_many评论),因为你没有通过表或外键的has_many。
INSERT INTO user_groups (user_id, group_id) VALUES (23, 54)
vs
usergroups:user_id = {54,108,32,..}
groupsuser:group_id = {23,12,645,..}
还有更多的补充逻辑示例,应用程序需要复制正常关系数据库使用的一些基本功能。所有这些原因使OKM的声音听起来像鞋子一样。
有没有?有什么理由没有?
答案 0 :(得分:4)
SQL的设计目标之一是可以在任何关系数据库中存储/查询任何数据 - 平台之间存在一些差异,但一般来说,处理特定数据结构的正确方法是众所周知的,并且很容易自动化但是需要相当冗长的代码。 NoSQL不是这种情况 - 通常您将直接存储应用程序中使用的数据,而不是尝试将其映射到关系结构,并且没有连接或其他对象/关系差异,映射代码是微不足道的。
除了生成样板数据访问代码之外,ORM的主要目的之一是抽象平台之间的差异。根据我的经验,切换平台的能力一直纯粹是理论上的,这种最低的公分母方法根本不适用于NoSQL,因为平台通常专门针对其他平台上没有的功能而选择。您的示例仅适用于最琐碎的键值存储 - 根据您的平台,您最有可能拥有一些有用的附加命令,因此您的第一个示例可能是
MGET用户:id:name user:id:email ...(multiget - 在一次通话中获取任意数量的键)
获取用户:id:*(密钥通配符)
HGETALL用户:id(redis hash - 获取用户的所有子键)
您可能还将您的用户对象以序列化形式存储 - 与关系数据库不同,这不会破坏您的所有查询。
如果您的平台没有内置支持,使用列表并不是很好 - 本机列表/集支持是我喜欢使用redis的原因之一 - 但除了可能需要锁之外,它并不比获取列表更糟糕超出sql。
值得注意的是,您可能不需要在sql中定义的所有关系 - 例如,如果您有一个包含一百万用户的组,则获取组中所有用户的列表的能力完全没用,所以你永远不会创建groupsuser列表,而不是一个单独的usergroups列表有user:id:groups作为多值属性。如果您只需要检查成员资格,可以将密钥设置为用户组:userid:groupid并获取恒定时间查找。
我发现在索引而不是关系方面进行思考是有帮助的 - 在设置数据访问代码时,决定需要查询哪些字段,并在写入这些字段时添加适当的索引记录。
答案 1 :(得分:4)
Ruby的DataMapper项目是一个ORM,很乐意通过使用适配器与键值存储进行对话。
Redis和MongoDB已经存在适配器。 CouchDB有一个适配器 - 它没有维护,但有一点它工作得很好。我认为任何人都没有对Cassandra做过任何事情,但没有理由不能做到。 Google App Engine的Dubious framework采用与Data Mapper非常相似的方法,使数据存储可供应用程序使用。
因此,使用键值存储进行ORM是非常可能的。 ORM确实需要避免假设SQL是它的主要词汇。
答案 2 :(得分:0)
ORM没有很好地映射到键值存储的无模式特性。话虽这么说,如果你使用的是Riak和Ruby,你可以看一下Ripple。 Riak还有许多其他驱动程序可能适合您的语言。
如果你正在研究MongoDB(更多的是文件存储而不是k / v存储),可以使用drivers个。{/ p>
答案 3 :(得分:0)
UNIVERSE数据库是Pick的后代,它允许您存储给定键的键值对列表。然而,这是一项非常古老的技术,很久以前世界就逃离了这些数据库。
您可以在具有三列表
的SQL数据库中实现此功能 CREATE TABLE ATTRS ( KEYVAL VARCHAR(32),
ATTRNAME VARCHAR(32),
ATTRVAR VARCHAR(1024)
)
虽然如果你提出这个问题,大多数DBA会用非常厚的Codd和Date精装版打击你,但它实际上是打包应用程序中非常常见的模式,允许你向系统添加特定于站点的属性。
总结Richrd Stallmans对LISP的评论。 “任何功能合理的数据存储系统最终都会最终实现自己的RDBMS版本。”