我正在研究不同类型的NoSQL数据库类型,我正试图围绕列族商店的数据模型,如Bigtable,HBase和Cassandra.
有些人将列族描述为行的集合,其中每行包含列[ 1 ],[ 2 ].此模型的一个示例(列族是大写的):
{ "USER": { "codinghorror": { "name": "Jeff", "blog": "http://codinghorror.com/" }, "jonskeet": { "name": "Jon Skeet", "email": "jskeet@site.com" } }, "BOOKMARK": { "codinghorror": { "http://codinghorror.com/": "My awesome blog", "http://unicorns.com/": "Weaponized ponies" }, "jonskeet": { "http://msmvps.com/blogs/jon_skeet/": "Coding Blog", "http://manning.com/skeet2/": "C# in Depth, Second Edition" } } }
其他站点将列族描述为一行中的 一组相关列[ 3 ],[ 4 ].上一个示例中的数据以这种方式建模:
{ "codinghorror": { "USER": { "name": "Jeff", "blog": "http://codinghorror.com/" }, "BOOKMARK": { "http://codinghorror.com/": "My awesome blog", "http://unicorns.com/": "Weaponized ponies" } }, "jonskeet": { "USER": { "name": "Jon Skeet", "email": "jskeet@site.com" }, "BOOKMARK": { "http://msmvps.com/blogs/jon_skeet/": "Coding Blog", "http://manning.com/skeet2/": "C# in Depth, Second Edition" } } }
后面一个可能的理由第一个模型是不是所有的列族有这样的关系USER
和BOOKMARK
事情.这意味着并非所有列族都包含相同的键.从这个角度来看,将列族置于外层感觉更自然.
名称"列族"表示一组列.这正是第二个模型中列族的呈现方式.
两种模型都是数据的有效表示.我意识到这些表示仅仅是为了向人类传播数据; 应用程序不会以这种方式"思考"数据.
列族的"标准"定义是什么?它是行的集合,还是一行中的一组相关列?
我必须写一篇关于这个主题的论文,所以我也对人们通常如何向其他人解释"列族"概念感兴趣.这两种模型似乎都相互矛盾.我想使用'正确'或普遍接受的模型来描述列族商店.
我已经用第二个模型解决了我在论文中解释数据模型的问题.我如何仍有兴趣你解释列的夫妻老婆店的其他人的数据模型.
我想,Cassandra数据库遵循你的第一个模型.ColumnFamily是一组行,它们可以以稀疏的方式包含任何列(因此,如果需要,每行可以具有不同的列名集合).连续允许的列数几乎是无限的(Cassandra v0.7中为20亿).
关键是,根据定义,行键在列族中必须是唯一的 - 但可以在其他列族中重复使用.因此,您可以在不同的ColumnFamilies中存储有关相同密钥的不相关数据.
在Cassandra中,这很重要,因为特定列族中的数据存储在磁盘上的相同文件中 - 因此在同一ColumnFamily中放置可能一起检索的数据项更有效.这在一定程度上是一个实际的速度问题,但也是将数据组织成一个清晰的模式的问题.这涉及到您的第二个定义 - 可能会将有关特定键的所有数据都视为"行",但会按列族进行分区.但是,在Cassandra中,它实际上不是一行,因为一个ColumnFamily中的数据可以独立于同一行键的其他ColumnFamilies中的数据进行更改.
您描述的两种模型都是相同的.
列族是:
Key -> Key -> (Set of key/value pairs)
从概念上讲,它变成:
Table -> Row -> (Column1/Value1, Column2/Value2, ...)
将其视为键/值对映射的映射.
UserProfile = { Cassandra = [emailAddress:"cassandra@apache.org", age:20], TerryCho = [emailAddress:"terry.cho@apache.org", gender:"male"], Cath = [emailAddress:"cath@apache.org", age:20, gender:"female", address:"Seoul"], }
以上是列族的示例.如果你要将它制成表格,你会得到一个名为UserProfile的表,它看起来像:
UserName | Email | Age | Gender | Address Cassandra | cassandra@apache.org | 20 | null | null TerryCho | terry.cho@apache.org | null | male | null Cath | cath@apache.org | 20 | female | Seoul
令人困惑的部分是,我们习惯于思考它们时,实际上没有一列或一行.有一堆"列族"按名称(键)查询.这些系列包含一组键/值对,它们也通过名称(行键)查询,最后,也可以按名称(列键)查找集合中的每个值.
如果您需要表格参考点,"列族"将是您的"表格".其中的每一组"k/v对"都是你的"行".每个"集合对"将是"列名称及其值".
在内部,每个列familly中的数据将被存储在一起,并且它将被存储使得行一个接一个地存储,并且在每一行中,列是一个接一个的.所以你得到了row1 -> col1/val1, col2/val2, ... , row2 -> col1/val1 ... , ... -> ...
.因此,从这个意义上讲,数据的存储更像是行存储,而不像列存储.
总而言之,这里的词语选择是不幸和误导的.列族中的列应该被称为属性.行应该被称为属性集.列族应该被称为属性族.与经典表格词汇的关系是微弱和误导的,因为它实际上是非常不同的.