neo4j(图数据库)
ER图转neo4j 官网说法
下图源于官网 浅分析一波
仔细的看上面的人er图
你会发现 Person中有 address的主键 address_id
也就是说 person 有了外键address_id
转到neo4j中 perdon和address也就有了关系
person-------->address 也就有了 LIVES_AT的关系
类似与上图 course和student之间有一个表sutdent_course存储关系
order和其他四个之间的关系不在赘述
Hbases(列存储与键值存储结合)
1、Hbase采用面向列(列族)加键值对的存储模式
2、可以便捷的实现横向扩展
3、可以自动的实现数据分片
关系数据库(面向行)
Hbase的数据结构(面向列)
Hbase数据存储方式
通过插入语句意会一下传说中的Hbase
插入语句
put 'player','001','basic:playername','Micheal Jordan',1
put 'player','002','basic:fistername','kobe'
put 'player','002','basic:lastername','byrant'
看似毫无章法 实则无迹可寻
对于以上插入语句
- 第一个参数是表名
- 第二个参数为行建的名称,一般为字符串类型
- 第三个参数是列族和列的名字,中间冒号隔开。列族的名字必须是已存在的
- 第四个参数为cell的值
- 第五个参数是时间戳,或者数据版本号,数值越大表示时间或版本越新
马克思告诉我们要透过现象看本质
通过这简单的几条插入语句 很难可以看出
列族需要在建表时预先定义
create 'player','basic'
create 'player','basic'.'advanced'
第一条语句表示建立一个叫player
的表,其中包含一个列族basic
第二条命令表示player
表中创建两个列族basic
和advanced
由此可推对于一个表 ,表名和列族是固定的 ,
那么回到上面的插入语句不难看出
每一行数据之间并没有太大关系 ,你有那一列和我有那一列没半毛钱关系
更像是键值对
这可能就是所为的 面向列存储
这有点颠覆我们为对数据库的一般认知 (应该是受mysql的影响)
修改语句
put 'player','001','basic:playername','air Jordan',2
由此可见
也就是说Hbase不能真正修改只是 插入了一条新的把以前的覆盖了
MongoDB(文档数据库)
子文档一对一
以顾客地址为例
每个顾客对应一个地址
如果用范式化的数据模型,address文档包含对customer文档的引用:
// customer 文档
{
_id: "joe",
name: "Joe Bookreader"
}
// address 文档
{
customer_id: "joe",
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
子文档合并
{
_id: "joe",
name: "Joe Bookreader",
address: { // address 作为子文档
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
}
子文档一对多
使用范式化数据模型,多个address文档包含对customer文档的引用
{
_id: "joe",
name: "Joe Bookreader"
}
{
customer_id: "joe",
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
{
customer_id: "joe",
street: "1 Some Other Street",
city: "Boston",
state: "MA",
zip: "12345"
}
子文档合并
{
_id: "joe",
name: "Joe Bookreader",
addresses: [
{
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
},
{
street: "1 Some Other Street",
city: "Boston",
state: "MA",
zip: "12345"
}
]
}
引用一对多
以出版社和书为例子,
每个出版社可以对应多本书。
如果使用子文档,将publisher文档嵌入book文档中,会导致publisher信息重复:
{
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher: { // publisher
name: "O'Reilly Media",
founded: 1980,
location: "CA"
}
}
{
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English",
publisher: { // publisher 重复
name: "O'Reilly Media",
founded: 1980,
location: "CA"
}
}
为了避免这种重复,可以使用引用,将publisher的信息单独保存到一个集合中。
{
name: "O'Reilly Media",
founded: 1980,
location: "CA",
books: [123456789, 234567890, ...] // 通过数组字段,存储对book的引用,但是数组将不断变大
}
{
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English"
}
{
_id: 234567890,
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English"
}
但是这种情况也有毛病
如果publisher发布的book数量巨大且没有限制,
这样的数据模型将导致不断地变化,
数组不断增长。
当然也有对应的解决方案
在book中包含对publisher的引用
{
_id: "oreilly",
name: "O'Reilly Media",
founded: 1980,
location: "CA"
}
{
_id: 123456789,
title: "MongoDB: The Definitive Guide",
author: [ "Kristina Chodorow", "Mike Dirolf" ],
published_date: ISODate("2010-09-24"),
pages: 216,
language: "English",
publisher_id: "oreilly" // book中引用publisher
}
{
_id: 234567890,
title: "50 Tips and Tricks for MongoDB Developer",
author: "Kristina Chodorow",
published_date: ISODate("2011-05-06"),
pages: 68,
language: "English",
publisher_id: "oreilly" // book中引用publisher
}
关系数据库与mongoDB数据库对比
SQL术语/概念 | MongoDB术语/概念 | 解释/说明 |
---|---|---|
database | database | 数据库 |
table | collection | 数据库表/集合 |
row | document | 数据记录行/文档 |
column | field | 数据字段/域 |
index | index | 索引 |
table joins | 表连接,MongoDB不支持 | |
嵌入文档 | MongoDB通过嵌入式文档来替代多表连接 | |
primary key | primary key | 主键,MongoDB自动将_id字段设置为主键 |
er图转MongoDB
两图并不完全对应 但意思就是那个意思 意会