假设 MongoDB 中有 3 个假设的集合:customers、orders和orderItems。
每个客户有多个订单,每个订单有多个订单项目。
以下是这 3 个集合的一些示例数据:
[
{
customer_id: 1,
name: "Jim Smith",
email: "jim.smith@example.com"
},
{
customer_id: 2,
name: "Bob Jones",
email: "bob.jones@example.com"
}
]
Run Code Online (Sandbox Code Playgroud)
[
{
order_id: 1,
customer_id: 1
},
{
order_id: 2,
customer_id: 1
}
]
Run Code Online (Sandbox Code Playgroud)
[
{
order_item_id: 1,
name: "Foo",
price: 4.99,
order_id: 1
},
{
order_item_id: 2,
name: "Bar",
price: 17.99,
order_id: 1
},
{
order_item_id: 3,
name: "baz",
price: 24.99, …Run Code Online (Sandbox Code Playgroud) 在设计数据密集型应用程序中,Martin 介绍了一种称为 LSM 树的数据结构。
主要由 3 部分组成:内存中的 memtable(通常是红黑树)、内存中的稀疏索引和磁盘上的 SSTable(又名段)。他们像这样一起工作:
当发生写入时,它首先进入内存表,当内存表变满时,所有数据都会刷新到新段中(所有键都已排序)。
当发生读取时,它首先查找内存表。如果该键不存在,它会查找稀疏索引,以了解该键可能驻留在哪个段。参见图 1。
定期进行压缩,将多个段合并为一个。参见图 2。
从图 2 中可以看出,键在段内排序,但键在段之间不排序。这让我想知道:我们如何维护索引中的稀疏索引 st 键具有递增的偏移量?
假设我有一个名为 的集合savedGamesFull。每当在此集合中创建文档时,它都会收到 Firebase 生成的 ID;然后,我重复使用该 ID,并将其提供给并行集合中的另一个文档savedGamesLight。
在另一个示例中,对于集合中的每个文档,在集合players中都会有一个具有相同 id 的文档。playerPublicProfilesplayerStats
基本上,这种命名方法所做的就是节省了几行代码,并且不需要userId在那些并行文档中保留该字段。
但在阅读了有关热点的内容后(尽管它似乎不适用于此处),我担心此命名可能存在问题。
那么,在多个不同的集合中使用相同的文档 ID 有什么缺点吗?
假设我正在编写一个日志分析应用程序.主域对象是LogEntry.此外.应用程序的用户定义了一个LogTopic,它描述了他们感兴趣的日志条目.当应用程序接收日志条目时,它会将它们添加到couchDB,并根据系统中的所有LogTopics检查它们,看它们是否与主题中的条件匹配.如果是,则系统应记录该条目与主题匹配.因此,LogEntries和LogTopics之间存在多对多关系.
如果我将它存储在RDBMS中,我会做类似的事情:
CREATE TABLE Entry (
id int,
...
)
CREATE TABLE Topic (
id int,
...
)
CREATE TABLE TopicEntryMap (
entry_id int,
topic_id int
)
Run Code Online (Sandbox Code Playgroud)
使用CouchDB我首先尝试只有两种文档类型.我有一个LogEntry类型,看起来像这样:
{
'type': 'LogEntry',
'severity': 'DEBUG',
...
}
Run Code Online (Sandbox Code Playgroud)
我有一个LogTopic类型,看起来像这样:
{
'type': 'LogTopic',
'matching_entries': ['log_entry_1','log_entry_12','log_entry_34',....],
...
}
Run Code Online (Sandbox Code Playgroud)
您可以通过使用matching_entries每个LogTopic文档中的字段来存储LogEntry文档ID列表来查看我表示关系.这在某种程度上可以正常工作,但是当多个客户端都试图向主题添加匹配条目时,我遇到了问题.两者都尝试乐观更新,一个失败.我现在使用的解决方案是基本上重现RDBMS方法,并添加第三种文档类型,如:
{
'type':'LogTopicToLogEntryMap',
'topic_id':'topic_12',
'entry_id':'entry_15'
}
Run Code Online (Sandbox Code Playgroud)
这工作,并通过并发更新问题,但我有两个保留:
任何人都有更好的解决方案吗?如果我也发布了我正在使用的观点会有帮助吗?
我正在努力解决复杂的事情(因为它在我看来).
我有下一个实体:
玩家(其中很少,名字如"John","Peter"等).每个都有唯一的ID.为简单起见,我们认为这是他们的名字.
游戏(其中很少,名为"捉迷藏","跳跃和奔跑"等).相同 - 每个都有唯一的ID.为了简单起见,现在让它成为它的名字.
SCORE(这是数字).
那么,它是如何工作的.
每个玩家都可以玩多个游戏.他在每场比赛中获得了一些分数.
我需要建立评级表 - 而不是一个!
表#1:最常玩游戏表#2:所有游戏中的最佳玩家(比如每个游戏中的总SCORE).表#3:每个GAME的最佳玩家(特别是那个GAME的SCORE).
我可以马上建立一些东西,但那不行.我将有超过10,000名球员; 和15场比赛,肯定会增长.对于游戏中的玩家,得分可以低至0,并且高达1,000,000(不确定此时是否可以更高).所以我真的需要一些相关数据.
有什么建议?
我打算用SQL来做,但可能只是用它来进行键值存储; 任何事情 - 欢迎任何想法.
谢谢!
几天前我在cassandra数据库引擎上听说过,并在上面搜索一个很好的文档.在研究了cassandra后,我得到的cassandra比其他数据引擎更具可扩展性.我也在Amazon SimpleDB上阅读,但由于SimpleDB的限制为10GB/table,而Google Datastore比Amazon SimpleDB慢,我不想使用它们(Google Datastore,Amazon SimpleDB).因此,为了使我们的网站使用大量数据扩展特别高的写入速率,我喜欢使用Cassandra作为我们的数据引擎.
但在开始使用cassandra之前,我对"如何使用casssandra处理复杂数据"感到困惑.我给你下面的MySQL数据库结构,请阅读这个并给我一个很好的建议.
用户表
hasColum ID主要
hasColum电子邮件唯一
hasColum FirstName
hasColum LastName
类别表
hasColum ID主要
hasColum父
hasColum类别
帖子表
hasColum ID主要
hasColum UID索引外键链接到用户 - > ID
hasColum CID索引外键链接到Category-> ID
hasColum Title
hasColum Post Index
hasColum PunDate
注释
hasColum ID primary
hasColum UID索引外键链接到
users- > ID hasColum PID索引外键链接到Posts-> ID
hasColum Comment
用户组
hasColum ID主要
hasColum名称
UserToGroup表(仅限多对多关系)
hasColum UID外键链接到Users-> ID
hasColum GID外键链接到Group-> ID
最后,为了您的信息,我喜欢使用SimpleCassie PHP类http://code.google.com/p/simpletools-php/ 因此,如果您可以使用SimpleCassie给我示例,那将非常有用
我正在评估一些NoSQL实现(目前是RavenDB和MongoDB),作为一种解决一组特定需求的方法,这些需求涉及无模式数据的存储/检索.我想得到一些关于NoSQL是否应该是我应该查看的方向的反馈,或者是否还有其他(可能更简单的)选项.
基本上我们有一个软件产品(除其他外)定义了一个基本域模型,该模型由几个相关实体组成,每个相关实体都有许多属性(键/值).当我们向客户发布时,我们与他们一起设置属性和值,这实际上是系统的配置.这是相当简单的,因为设计是预先知道的,我们不需要任何动态来实现这一点并使其执行(我们将使用RDBMS).这些属性不是预先知道的,但这也不是问题,因为系统的这一部分几乎围绕属性模型.
问题在于,对于不同的客户,在我们发布并投入生产之后,我们发现我们需要查询特定的属性数据集,这些属性数据在编译和发布代码时(在我们配置属性之前)一无所知顾客).我们基本上需要从我们可以存储的属性映射中生成数据(我们不会预先知道结构),然后以我们无法预料的方式查询存储的数据.现在的想法是我们可以创建在处理期间受到影响的钩子,并允许我们插入库(可能通过MEF)创建数据以便存储,然后在需要时查询它(不用于报告 - 通常用于创建其他数据/属性).
(请注意,创建钩子和插件库是一个单独的问题,并不打算成为此问题的一部分.)
常见的情况可能是:"我想知道过去10天内xxx发生了多少次".所以我会创建一个能够识别xxx已经发生的插件,并将其写入带有日期/时间的数据存储.然后我将创建另一个执行查询的插件(可能在同一个DLL中),并向名为"CountOfxxxInLast10Days"的模型添加一个属性.另一种情况可能是创建可配置的查找.所以我可能有一个在启动时运行的插件来创建/更新可以将一个属性值转换为另一个属性值的查找数据表,或者(更可能)将转换为查找值的一系列值.因此转换插件可能会添加一个包含列的表:bottom_value,top_value,multiplier,查询插件将使用属性值查询表,如"
在某些情况下,旧数据可能会在指定的时间段后被清除.在上述第一种情况中,可能需要从超过十天的商店/缓存中删除数据.
在其他情况下,数据需要永久保留,如上面的第二种情况.这种数据可能只是在启动时重新创建,而不是在永久存储中保存.
其他要求:
我们现在非常致力于.Net平台,因此任何选项都必须拥有可靠的.Net客户端/ API.
我们已经考虑过为我们的下一个项目运行一个noSQL数据库.但是,我们不确定哪个平台能够为我们提供最佳可用性,并且具有最好的内置复制功能/功能来提供这一功能 - 最难以解决.
现在,Cassandra似乎是最好的候选人,但我们希望从那些在这方面有更多经验的人那里听到更多关于这一点的信息,然后我们会这样做.
非常感谢!
我们要解决客户的需要的基于Web的应用程序,它拥有的大的产品和他们的数据量-包括价格,重量,物理volyme,等等.
除了价格之外的所有东西都是数据,这些数据将被存储一次,然后可能不会改变.另一方面,价格将至少每天更新一次,以适应不断变化的货币汇率.因此,我们已经考虑了一些关于使用noSQL数据库的问题,但是我还没有经验来决定它是一个好主意还是只是一个奇特而现代的解决方案来解决我们的问题?
是吗?
非常感谢!