MongoDB 学习一,关于表结构

http://blog.163.com/pjt_ren/blog/static/188250602014121103854532/

 
 

MySql一直是性价比最高的关系型数据库典范

MongoDB带来了关系数据库以外的NoSql体验。

  让我们看一个简单的例子,我们将如何为MySQL(或任何关系数据库)和MongoDB中创建一个数据结构。

MySql设计

我们假设设计个表:

People 人物信息表  包含ID 和名字字段

passports 护照表 ,主要包含 对应的people表的外键ID ,所属国家,和护照有效期

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql > select * from people ;
+ -- -- + -- -- -- -- -- -- +
| id | name        |
+ -- -- + -- -- -- -- -- -- +
|    1 | Stephane    |
|    2 | John        |
|    3 | Michael      |
|    4 | Cinderella |
+ -- -- + -- -- -- -- -- -- +
mysql > select * from passports ;
+ -- -- + -- -- -- -- -- - + -- -- -- -- - + -- -- -- -- -- -- - +
| id | people_id | country | valid_until |
+ -- -- + -- -- -- -- -- - + -- -- -- -- - + -- -- -- -- -- -- - +
|    4 |          1 | FR        | 2020 - 01 - 01    |
|    5 |          2 | US        | 2020 - 01 - 01    |
|    6 |          3 | RU        | 2020 - 01 - 01    |
+ -- -- + -- -- -- -- -- - + -- -- -- -- - + -- -- -- -- -- -- - +

于是你接下来可以操作如下基本功能:

一共有多少人

 
1
SELECT count ( * ) FROM people

查询出 stephane 的护照有效期

 
1
SELECT valid_until from passports ps join people pl ON ps . people_id = pl . id WHERE name = 'Stephane'

有多少人木有护照

 

 
1
SELECT name FROM people pl LEFT JOIN passports ps ON ps . people_id = pl . id WHERE ps . id IS NULL

 

MongoDB的设计

接下来是在MongoDB中进行设计

上述关系型数据库中使用三范式,固然是规范的,但是效率不高,因为关联度不高的情况下完全没有必要使用三范式来设计。

  一种是“直筒式”的设计,和关系型数据库的理解区别不大

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
     "_id" : ObjectId ( "51f7be1cd6189a56c399d3bf" ) ,
     "name" : "Stephane" ,
     "country" : "FR" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
}
{
     "_id" : ObjectId ( "51f7be3fd6189a56c399d3c0" ) ,
     "name" : "John" ,
     "country" : "US" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
}
{
     "_id" : ObjectId ( "51f7be4dd6189a56c399d3c1" ) ,
     "name" : "Michael" ,
     "country" : "RU" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
}
{ "_id" : ObjectId ( "51f7be5cd6189a56c399d3c2" ) , "name" : "Cinderella" }

MongoDB 无固定结构,每张表每段数据可以有不同的结构,这既是好处也是缺点,缺点在于你必须很了解MongoDB的表结构,这其实给维护人员带来一定的不适应和麻烦。

 2、以下是MongoDb特征的设计方法, 既:把people信息和护照信息柔和在一起

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
     "_id" : ObjectId ( "51f7c0048ded44d5ebb83774" ) ,
     "name" : "Stephane" ,
     "passport" : {
         "country" : "FR" ,
         "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
     }
}
{
     "_id" : ObjectId ( "51f7c70e8ded44d5ebb83775" ) ,
     "name" : "John" ,
     "passport" : {
         "country" : "US" ,
         "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
     }
}
{
     "_id" : ObjectId ( "51f7c71b8ded44d5ebb83776" ) ,
     "name" : "Michael" ,
     "passport" : {
         "country" : "RU" ,
         "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
     }
}
{ "_id" : ObjectId ( "51f7c7258ded44d5ebb83777" ) , "name" : "Cinderella" }

3、同样的,上述结构也可以字段反过来设计,如果没有“valid_until”字段代表没有护照

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
     "_id" : ObjectId ( "51f7c7e58ded44d5ebb8377b" ) ,
     "country" : "FR" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" ) ,
     "person" : {
         "name" : "Stephane"
     }
}
{
     "_id" : ObjectId ( "51f7c7ec8ded44d5ebb8377c" ) ,
     "country" : "US" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" ) ,
     "person" : {
         "name" : "John"
     }
}
{
     "_id" : ObjectId ( "51f7c7fa8ded44d5ebb8377d" ) ,
     "country" : "RU" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" ) ,
     "person" : {
         "name" : "Michael"
     }
}
{
     "_id" : ObjectId ( "51f7c8058ded44d5ebb8377e" ) ,
     "person" : {
         "name" : "Cinderella"
     }
}

 

 

结论

我们看到MySQL和MongoDB的根本区别之一,

1、使用MongoDB, 架构设计变得无比重要,一旦中间有个环节设计的有问题,将会带来灾难性的维护和返工后果,后面更不用提优化。但是同样的问题也逼着我们去做一个好的架构养成好的习惯。

2、 哪种方式更好?当然,有没有明确的答案。不同的环境使用不同的方式,就像上面这个例子完全使用MongoDB效率更高,譬如单表数据达到1000 万,mysql关联查询是很坑爹的。对于多业务逻辑复杂关联设计,MongoDB不是不能胜任,关键我们不能保证我们的软件需求像老外那样不会一直变更或 者推翻重写,所以用mysql更易于维护

2014-02-21 10:38:54|  分类: MongoDB |  标签:mongodb   |举报 |字号 订阅

 
 

MySql一直是性价比最高的关系型数据库典范

MongoDB带来了关系数据库以外的NoSql体验。

  让我们看一个简单的例子,我们将如何为MySQL(或任何关系数据库)和MongoDB中创建一个数据结构。

MySql设计

我们假设设计个表:

People 人物信息表  包含ID 和名字字段

passports 护照表 ,主要包含 对应的people表的外键ID ,所属国家,和护照有效期

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql > select * from people ;
+ -- -- + -- -- -- -- -- -- +
| id | name        |
+ -- -- + -- -- -- -- -- -- +
|    1 | Stephane    |
|    2 | John        |
|    3 | Michael      |
|    4 | Cinderella |
+ -- -- + -- -- -- -- -- -- +
mysql > select * from passports ;
+ -- -- + -- -- -- -- -- - + -- -- -- -- - + -- -- -- -- -- -- - +
| id | people_id | country | valid_until |
+ -- -- + -- -- -- -- -- - + -- -- -- -- - + -- -- -- -- -- -- - +
|    4 |          1 | FR        | 2020 - 01 - 01    |
|    5 |          2 | US        | 2020 - 01 - 01    |
|    6 |          3 | RU        | 2020 - 01 - 01    |
+ -- -- + -- -- -- -- -- - + -- -- -- -- - + -- -- -- -- -- -- - +

于是你接下来可以操作如下基本功能:

一共有多少人

 
1
SELECT count ( * ) FROM people

查询出 stephane 的护照有效期

 
1
SELECT valid_until from passports ps join people pl ON ps . people_id = pl . id WHERE name = 'Stephane'

有多少人木有护照

 

 
1
SELECT name FROM people pl LEFT JOIN passports ps ON ps . people_id = pl . id WHERE ps . id IS NULL

 

MongoDB的设计

接下来是在MongoDB中进行设计

上述关系型数据库中使用三范式,固然是规范的,但是效率不高,因为关联度不高的情况下完全没有必要使用三范式来设计。

  一种是“直筒式”的设计,和关系型数据库的理解区别不大

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
     "_id" : ObjectId ( "51f7be1cd6189a56c399d3bf" ) ,
     "name" : "Stephane" ,
     "country" : "FR" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
}
{
     "_id" : ObjectId ( "51f7be3fd6189a56c399d3c0" ) ,
     "name" : "John" ,
     "country" : "US" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
}
{
     "_id" : ObjectId ( "51f7be4dd6189a56c399d3c1" ) ,
     "name" : "Michael" ,
     "country" : "RU" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
}
{ "_id" : ObjectId ( "51f7be5cd6189a56c399d3c2" ) , "name" : "Cinderella" }

MongoDB 无固定结构,每张表每段数据可以有不同的结构,这既是好处也是缺点,缺点在于你必须很了解MongoDB的表结构,这其实给维护人员带来一定的不适应和麻烦。

 2、以下是MongoDb特征的设计方法, 既:把people信息和护照信息柔和在一起

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
     "_id" : ObjectId ( "51f7c0048ded44d5ebb83774" ) ,
     "name" : "Stephane" ,
     "passport" : {
         "country" : "FR" ,
         "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
     }
}
{
     "_id" : ObjectId ( "51f7c70e8ded44d5ebb83775" ) ,
     "name" : "John" ,
     "passport" : {
         "country" : "US" ,
         "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
     }
}
{
     "_id" : ObjectId ( "51f7c71b8ded44d5ebb83776" ) ,
     "name" : "Michael" ,
     "passport" : {
         "country" : "RU" ,
         "valid_until" : ISODate ( "2019-12-31T23:00:00Z" )
     }
}
{ "_id" : ObjectId ( "51f7c7258ded44d5ebb83777" ) , "name" : "Cinderella" }

3、同样的,上述结构也可以字段反过来设计,如果没有“valid_until”字段代表没有护照

 

 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
     "_id" : ObjectId ( "51f7c7e58ded44d5ebb8377b" ) ,
     "country" : "FR" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" ) ,
     "person" : {
         "name" : "Stephane"
     }
}
{
     "_id" : ObjectId ( "51f7c7ec8ded44d5ebb8377c" ) ,
     "country" : "US" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" ) ,
     "person" : {
         "name" : "John"
     }
}
{
     "_id" : ObjectId ( "51f7c7fa8ded44d5ebb8377d" ) ,
     "country" : "RU" ,
     "valid_until" : ISODate ( "2019-12-31T23:00:00Z" ) ,
     "person" : {
         "name" : "Michael"
     }
}
{
     "_id" : ObjectId ( "51f7c8058ded44d5ebb8377e" ) ,
     "person" : {
         "name" : "Cinderella"
     }
}

 

 

结论

我们看到MySQL和MongoDB的根本区别之一,

1、使用MongoDB, 架构设计变得无比重要,一旦中间有个环节设计的有问题,将会带来灾难性的维护和返工后果,后面更不用提优化。但是同样的问题也逼着我们去做一个好的架构养成好的习惯。

2、 哪种方式更好?当然,有没有明确的答案。不同的环境使用不同的方式,就像上面这个例子完全使用MongoDB效率更高,譬如单表数据达到1000 万,mysql关联查询是很坑爹的。对于多业务逻辑复杂关联设计,MongoDB不是不能胜任,关键我们不能保证我们的软件需求像老外那样不会一直变更或 者推翻重写,所以用mysql更易于维护

转载于:https://www.cnblogs.com/gzmg/p/3711851.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值