Internet database schema design ideas

First, the 58 city database schema design ideas

(1) Availability Design

Solution: Redundant Copy +

Side effects: copy + redundancy will lead to consistency problems

To ensure that "read" the availability Method: copying data from the library, redundant, as FIG.

 0
Problems caused by: master and slave is inconsistent

Solution: see below

Guarantee "write" high availability General Procedure: Two main mode, i.e. the master copy library (Many companies use a single master, this case can not guarantee the availability of write), redundant data, as in FIG.

 1
Problems associated with: double master key synchronization conflicts, cited inconsistencies

solution:

a) a program: a guaranteed service level key database or not conflict on two main

b) Scheme II: see below

58 to ensure that city "write" high availability Method: "Dual" when the "master-slave" with, not separate read and write, in a case where the "master" hang "from" (actually another master), a top upper, below

 2
Advantages: read and written to the main, solve the problem of consistency; "Dual" when the "master-slave" as used to solve the problem of usability

Problems associated with: how to read performance expansion? Solution see below

(2) read performance design: how to extend the read performance

The most common method is to create an index

Establish a lot of indexing, side effects are:

a) reduces the write performance

b) index accounted for more than a memory, in memory of the data is less, data hit rate is low, IO number on more

But if think, different libraries can create different indexes it? As shown below

 3
TIPS: different libraries can create different indexes

Main library provides write-only, not indexed

online from the library only provide online reading, the establishment of online reading index

offline from the library only provide offline reading, the index established offline reading

Improve read performance common program two, increase from the library

4

As already mentioned, this approach will lead to a master-slave inconsistencies, the more from the library, the master from the longer the delay, the more serious problem of inconsistency

This approach is common, but 58 did not use

Option Three improve read performance, increase the cache

Traditional cache usage is:

A) The occurrence of a write request, to eliminate caching, database write

B) When a read request occurs, the first read buffer, is returned HIT, Miss database is read into the data buffer (old data into the cache at this time may be), as shown below

 5
Problems caused by:

a) As described above, data replication can cause consistency problems, due to the presence of delay from the master, the database may lead to inconsistent data cache

b)所有app业务层都要关注缓存,无法屏蔽“主+从+缓存”的复杂性

58同城缓存使用方案:服务+数据+缓存

 6
好处是:

1)引入服务层屏蔽“数据库+缓存”

2)不做读写分离,读写都到主的模式,不会引发不一致

(3)一致性设计

主从不一致解决方案

方案一:引入中间件

 7
中间件将key上的写路由到主,在一定时间范围内(主从同步完成的经验时间),该key上的读也路由到主

方案二:读写都到主

8

上文已经提到,58同城采用了这种方法,不做读写分离,不会不一致

数据库与缓存不一致解决方案

两次淘汰法

9

异常的读写时序,或导致旧数据入缓存,一次淘汰不够,要进行二次淘汰

a)发生写请求时,先淘汰缓存,再写数据库,额外增加一个timer,一定时间(主从同步完成的经验时间)后再次淘汰

b)发生读请求时,先读缓存,hit则返回,miss则读数据库并将数据入缓存(此时可能旧数据入缓存,但会被二次淘汰淘汰掉,最终不会引发不一致)

(4)扩展性设计

(4.1)58同城秒级别数据扩容

需求:原来水平切分为N个库,现在要扩充为2N个库,希望不影响服务,在秒级别完成

 10
最开始,分为2库,0库和1库,均采用“双主当主从用”的模式保证可用性

 11
接下来,将从库提升,并修改服务端配置,秒级完成扩库

由于是2扩4,不会存在数据迁移,原来的0库变为0库+2库,原来的1库变为1库和3库

此时损失的是数据的可用性

 12
最后,解除旧的双主同步(0库和2库不会数据冲突),为了保证可用性增加新的双主同步,并删除掉多余的数据

这种方案可以秒级完成N库到2N库的扩容。

存在的问题:只能完成N库扩2N库的扩容(不需要数据迁移),非通用扩容方案(例如3库扩4库就无法完成)

(4.2)非指数扩容,数据库增加字段,数据迁移

[这些方法在(上)篇中都已经介绍过,此处不再冗余,有兴趣的朋友回复“同城”回看(上)篇]

方案一:追日志方案

方案二:双写方案

(4.3)水平切分怎么切

四类场景覆盖99%拆库业务

a)“单key”场景,用户库如何拆分: user(uid, XXOO)

b)“1对多”场景,帖子库如何拆分: tiezi(tid, uid, XXOO)

c)“多对多”场景,好友库如何拆分: friend(uid, friend_uid, XXOO)

d)“多key”场景,订单库如何拆分:order(oid, buyer_id, seller_id, XXOO)

[这些拆库方案在(上)篇中都已经介绍过,此处不再冗余,有兴趣的朋友回复“同城”回看(上)篇]

(5)海量数据下,SQL怎么玩

不会这么玩

a)各种联合查询

b)子查询

c)触发器

d)用户自定义函数

e)“事务”都用的很少

原因:对数据库性能影响极大

拆库后,IN查询怎么玩[回复“同城”回看(上)篇]

拆库后,非Partition key的查询怎么玩[回复“同城”回看(上)篇]

拆库后,夸库分页怎么玩?[回复“同城”回看(上)篇]

问题的提出与抽象:ORDER BY xxx OFFSET xxx LIMIT xxx

单机方案:ORDER BY time OFFSET 10000 LIMIT 100

分库后的难题:如何确认全局偏移量

分库后传统解决方案:查询改写+内存排序

a)ORDER BY time OFFSET 0 LIMIT 10000+100

b)对20200条记录进行排序

c)返回第10000至10100条记录

优化方案一:增加辅助id,以减少查询量

优化方案二:模糊查询

a)业务上:禁止查询XX页之后的数据

b)业务上:允许模糊返回 => 第100页数据的精确性真这么重要么?

最后的大招!!!(由于时间问题,只在DTCC2015上分享了哟)

优化方案三:终极方案,业务无损,查询改写与两段查询

需求:ORDER BY x OFFSET 10000 LIMIT 4; 如何在分库下实现(假设分3库)

步骤一、查询改写: ORDER BY x OFFSET 3333 LIMIT 4

[4,7,9,10] <= 1库返回

[3,5,6,7] <= 2库返回

[6,8,9,11] <= 3库返回

步骤二、找到步骤一返回的min和max,即3和11

步骤三、通过min和max二次查询:ORDER BY x WHERE x BETWEEN 3 AND 11

[3,4,7,9,10] <= 1库返回,4在1库offset是3333,于是3在1库的offset是3332

[3,5,6,7,11] <= 2库返回,3在2库offset是3333

[3,5,6,8,9,11] <= 3库返回,6在3库offset是3333,于是3在3库的offset是3331

步骤四、找出全局OFFSET

3是全局offset3332+3333+3331=9996

当当当当,跳过3,3,3,4,于是全局OFFSET 10000 LIMIT 4是[5,5,6,6]

总结:58同城数据库架构设计思路

(1)可用性,解决思路是冗余(复制)

(1.1)读可用性:多个从库

(1.2)写可用性:双主模式 or 双主当主从用(58的玩法)

(2)读性能,三种方式扩充读性能

(2.1)增加索引:主从上的索引可以不一样

(2.2)增加从库

(2.3)增加缓存:服务+缓存+数据一套(58的玩法)

(3)一致性

(3.1)主从不一致:引入中间层 or 读写都走主库(58的玩法)

(3.2)缓存不一致:双淘汰来解决缓存不一致问题

(4)扩展性

(4.1)数据扩容:提升从库,double主库,秒级扩容

(4.2)字段扩展:追日志法 or 双写法

(4.3)水平切分

(单key)用户库如何拆分:, user(uid XXOO)

(1对多)帖子库如何拆分: tiezi(tid, uid, XXOO)

(多对多)好友库如何拆分: friend(uid, friend_uid, XXOO)

(多key)订单库如何拆分:order(oid, buyer_id, seller_id, XXOO)

(5)SQL玩法

(5.0)不这么玩:联合查询,子查询,触发器,自定义函数,事务

(5.1)IN查询:分发MR or 拼装成不同SQL语句

(5.2)非partition key查询:定位一个库 or 分发MR

(5.3)夸库分页

(5.3.1)修改sql语句,服务内排序

(5.3.2)引入特殊id,减少返回数量

(5.3.3)业务优化,允许模糊查询

(5.3.4)查询改写,二段查询

58同城的案例到这儿

 

二、数据库之父Codd的12条法则

另外,我们回顾一下数据库之父Codd的12条法则,作为数据库设计的指导性方针:

  1. 信息法则
    关系数据库中的所有信息都用唯一的一种方式表示——表中的值。
  2. 保证访问法则
    依靠表名、主键值和列名的组合,保证能访问每个数据项。
  3. 空值的系统化处理
    支持空值(NULL),以系统化的方式处理空值,空值不依赖于数据类型。
  4. 基于关系模型的动态联机目录
    数据库的描述应该是自描述的,在逻辑级别上和普通数据采用同样的表示方式,即数据库必须含有描述该数据库结构的系统表或者数据库描述信息应该包含在用户可以访问的表中。
  5. 统一的数据子语言法则
    一个关系数据库系统可以支持几种语言和多种终端使用方式,但必须至少有一种语言,它的语句能够一某种定义良好的语法表示为字符串,并能全面地支持以下所有规则:数据定义、视图定义、数据操作、约束、授权以及事务。(这种语言就是SQL)
  6. 视图更新法则
    所有理论上可以更新的视图也可以由系统更新。
  7. 高级的插入、更新和删除操作
    把一个基础关系或派生关系作为单个操作对象处理的能力不仅适应于数据的检索,还适用于数据的插入、修改个删除,即在插入、修改和删除操作中数据行被视作集合。
  8. 数据的物理独立性
    不管数据库的数据在存储表示或访问方式上怎么变化,应用程序和终端活动都保持着逻辑上的不变性。
  9. 数据的逻辑独立性
    当对表做了理论上不会损害信息的改变时,应用程序和终端活动都会保持逻辑上的不变性。
  10. 数据完整性的独立性
    专用于某个关系型数据库的完整性约束必须可以用关系数据库子语言定义,而且可以存储在数据目录中,而非程序中。
  11. Distribution of independence
    regardless of whether the physical data in distributed storage, distribution or any time to change strategy, RDBMS data manipulation sublanguage must make the application and terminal activities remain invariant logical.
  12. Non-destructive rule
    if a relational database systems support some low-level (a single record processing) language, then the low-level language can not violate or bypass the higher-level language (once more than one record) specified integrity rules or constraints that user not violate the constraints of the database in any way.

 

Some experience:

  • Reduce dependence on database features
    function should be implemented by a program, rather than DB implementation. The reason is that, if the function is performed by DB, replacing the previous system of once powerful DBMS is better, some functions can not be achieved, then we will have to modify the code. Therefore, in order to prevent such situations occur, there should be a program to realize the function, the database is only responsible for storing data in order to achieve the lowest coupling.
  • Principles entity relationship definition
    When defining a relationship between the entity and when other entities, need to consider the following:
    • Involved entities to identify all entities involved in the relationship.
    • Ownership consider an entity that "owns" the situation of another entity.
    • Cardinality a number associated instance for another entity examples and considerations.



From the network data collection and integration, we want to help your software development. Other articles that might interest you:
the performance of enterprise applications in real-time measurement systems evolve
cloud computing reference architecture a few
smart mobile solution brief tour
of human resource management system evolution

If want to know more software, systems, IT, enterprise information, please pay attention to my micro-channel subscription number:

MegadotnetMicroMsg_thumb1_thumb1_thu[1]


Author: Petter Liu
Source: http://www.cnblogs.com/wintersun/
This article belongs to the author and blog Park total, welcome to reprint, but without the author's consent declared by this section must be retained, and given the apparent position of the original article page connection, otherwise the right to pursue legal responsibilities.
The article also posted on my blog, independent - Petter Liu Blog .

Original Address: https: //www.cnblogs.com/wintersun/p/4638176.html

First, the 58 city database schema design ideas

(1) Availability Design

Solution: Redundant Copy +

Side effects: copy + redundancy will lead to consistency problems

To ensure that "read" the availability Method: copying data from the library, redundant, as FIG.

 0
Problems caused by: master and slave is inconsistent

Solution: see below

Guarantee "write" high availability General Procedure: Two main mode, i.e. the master copy library (Many companies use a single master, this case can not guarantee the availability of write), redundant data, as in FIG.

 1
Problems associated with: double master key synchronization conflicts, cited inconsistencies

solution:

a) a program: a guaranteed service level key database or not conflict on two main

b) Scheme II: see below

58 to ensure that city "write" high availability Method: "Dual" when the "master-slave" with, not separate read and write, in a case where the "master" hang "from" (actually another master), a top upper, below

 2
Advantages: read and written to the main, solve the problem of consistency; "Dual" when the "master-slave" as used to solve the problem of usability

Problems associated with: how to read performance expansion? Solution see below

(2) read performance design: how to extend the read performance

The most common method is to create an index

Establish a lot of indexing, side effects are:

a) reduces the write performance

b) index accounted for more than a memory, in memory of the data is less, data hit rate is low, IO number on more

But if think, different libraries can create different indexes it? As shown below

 3
TIPS: different libraries can create different indexes

Main library provides write-only, not indexed

online from the library only provide online reading, the establishment of online reading index

offline从库只提供offline读,建立offline读索引

提高读性能常见方案二,增加从库

4

上文已经提到,这种方法会引发主从不一致问题,从库越多,主从时延越长,不一致问题越严重

这种方案很常见,但58没有采用

提高读性能方案三,增加缓存

传统缓存的用法是:

a)发生写请求时,先淘汰缓存,再写数据库

b)发生读请求时,先读缓存,hit则返回,miss则读数据库并将数据入缓存(此时可能旧数据入缓存),如下图

 5
带来的问题:

a)如上文所述,数据复制会引发一致性问题,由于主从延时的存在,可能引发缓存与数据库数据不一致

b)所有app业务层都要关注缓存,无法屏蔽“主+从+缓存”的复杂性

58同城缓存使用方案:服务+数据+缓存

 6
好处是:

1)引入服务层屏蔽“数据库+缓存”

2)不做读写分离,读写都到主的模式,不会引发不一致

(3)一致性设计

主从不一致解决方案

方案一:引入中间件

 7
中间件将key上的写路由到主,在一定时间范围内(主从同步完成的经验时间),该key上的读也路由到主

方案二:读写都到主

8

上文已经提到,58同城采用了这种方法,不做读写分离,不会不一致

数据库与缓存不一致解决方案

两次淘汰法

9

异常的读写时序,或导致旧数据入缓存,一次淘汰不够,要进行二次淘汰

a)发生写请求时,先淘汰缓存,再写数据库,额外增加一个timer,一定时间(主从同步完成的经验时间)后再次淘汰

b)发生读请求时,先读缓存,hit则返回,miss则读数据库并将数据入缓存(此时可能旧数据入缓存,但会被二次淘汰淘汰掉,最终不会引发不一致)

(4)扩展性设计

(4.1)58同城秒级别数据扩容

需求:原来水平切分为N个库,现在要扩充为2N个库,希望不影响服务,在秒级别完成

 10
最开始,分为2库,0库和1库,均采用“双主当主从用”的模式保证可用性

 11
接下来,将从库提升,并修改服务端配置,秒级完成扩库

由于是2扩4,不会存在数据迁移,原来的0库变为0库+2库,原来的1库变为1库和3库

此时损失的是数据的可用性

 12
最后,解除旧的双主同步(0库和2库不会数据冲突),为了保证可用性增加新的双主同步,并删除掉多余的数据

这种方案可以秒级完成N库到2N库的扩容。

存在的问题:只能完成N库扩2N库的扩容(不需要数据迁移),非通用扩容方案(例如3库扩4库就无法完成)

(4.2)非指数扩容,数据库增加字段,数据迁移

[这些方法在(上)篇中都已经介绍过,此处不再冗余,有兴趣的朋友回复“同城”回看(上)篇]

方案一:追日志方案

方案二:双写方案

(4.3)水平切分怎么切

四类场景覆盖99%拆库业务

a)“单key”场景,用户库如何拆分: user(uid, XXOO)

b)“1对多”场景,帖子库如何拆分: tiezi(tid, uid, XXOO)

c)“多对多”场景,好友库如何拆分: friend(uid, friend_uid, XXOO)

d)“多key”场景,订单库如何拆分:order(oid, buyer_id, seller_id, XXOO)

[这些拆库方案在(上)篇中都已经介绍过,此处不再冗余,有兴趣的朋友回复“同城”回看(上)篇]

(5)海量数据下,SQL怎么玩

不会这么玩

a)各种联合查询

b)子查询

c)触发器

d)用户自定义函数

e)“事务”都用的很少

原因:对数据库性能影响极大

拆库后,IN查询怎么玩[回复“同城”回看(上)篇]

拆库后,非Partition key的查询怎么玩[回复“同城”回看(上)篇]

拆库后,夸库分页怎么玩?[回复“同城”回看(上)篇]

问题的提出与抽象:ORDER BY xxx OFFSET xxx LIMIT xxx

单机方案:ORDER BY time OFFSET 10000 LIMIT 100

分库后的难题:如何确认全局偏移量

分库后传统解决方案:查询改写+内存排序

a)ORDER BY time OFFSET 0 LIMIT 10000+100

b)对20200条记录进行排序

c)返回第10000至10100条记录

优化方案一:增加辅助id,以减少查询量

优化方案二:模糊查询

a)业务上:禁止查询XX页之后的数据

b)业务上:允许模糊返回 => 第100页数据的精确性真这么重要么?

最后的大招!!!(由于时间问题,只在DTCC2015上分享了哟)

优化方案三:终极方案,业务无损,查询改写与两段查询

需求:ORDER BY x OFFSET 10000 LIMIT 4; 如何在分库下实现(假设分3库)

步骤一、查询改写: ORDER BY x OFFSET 3333 LIMIT 4

[4,7,9,10] <= 1库返回

[3,5,6,7] <= 2库返回

[6,8,9,11] <= 3库返回

步骤二、找到步骤一返回的min和max,即3和11

步骤三、通过min和max二次查询:ORDER BY x WHERE x BETWEEN 3 AND 11

[3,4,7,9,10] <= 1库返回,4在1库offset是3333,于是3在1库的offset是3332

[3,5,6,7,11] <= 2库返回,3在2库offset是3333

[3,5,6,8,9,11] <= 3库返回,6在3库offset是3333,于是3在3库的offset是3331

步骤四、找出全局OFFSET

3是全局offset3332+3333+3331=9996

当当当当,跳过3,3,3,4,于是全局OFFSET 10000 LIMIT 4是[5,5,6,6]

总结:58同城数据库架构设计思路

(1)可用性,解决思路是冗余(复制)

(1.1)读可用性:多个从库

(1.2)写可用性:双主模式 or 双主当主从用(58的玩法)

(2)读性能,三种方式扩充读性能

(2.1)增加索引:主从上的索引可以不一样

(2.2)增加从库

(2.3)增加缓存:服务+缓存+数据一套(58的玩法)

(3)一致性

(3.1)主从不一致:引入中间层 or 读写都走主库(58的玩法)

(3.2)缓存不一致:双淘汰来解决缓存不一致问题

(4)扩展性

(4.1)数据扩容:提升从库,double主库,秒级扩容

(4.2)字段扩展:追日志法 or 双写法

(4.3)水平切分

(单key)用户库如何拆分:, user(uid XXOO)

(1对多)帖子库如何拆分: tiezi(tid, uid, XXOO)

(多对多)好友库如何拆分: friend(uid, friend_uid, XXOO)

(多key)订单库如何拆分:order(oid, buyer_id, seller_id, XXOO)

(5)SQL玩法

(5.0)不这么玩:联合查询,子查询,触发器,自定义函数,事务

(5.1)IN查询:分发MR or 拼装成不同SQL语句

(5.2)非partition key查询:定位一个库 or 分发MR

(5.3)夸库分页

(5.3.1)修改sql语句,服务内排序

(5.3.2)引入特殊id,减少返回数量

(5.3.3)业务优化,允许模糊查询

(5.3.4)查询改写,二段查询

58同城的案例到这儿

 

二、数据库之父Codd的12条法则

另外,我们回顾一下数据库之父Codd的12条法则,作为数据库设计的指导性方针:

  1. 信息法则
    关系数据库中的所有信息都用唯一的一种方式表示——表中的值。
  2. 保证访问法则
    依靠表名、主键值和列名的组合,保证能访问每个数据项。
  3. 空值的系统化处理
    支持空值(NULL),以系统化的方式处理空值,空值不依赖于数据类型。
  4. 基于关系模型的动态联机目录
    数据库的描述应该是自描述的,在逻辑级别上和普通数据采用同样的表示方式,即数据库必须含有描述该数据库结构的系统表或者数据库描述信息应该包含在用户可以访问的表中。
  5. 统一的数据子语言法则
    一个关系数据库系统可以支持几种语言和多种终端使用方式,但必须至少有一种语言,它的语句能够一某种定义良好的语法表示为字符串,并能全面地支持以下所有规则:数据定义、视图定义、数据操作、约束、授权以及事务。(这种语言就是SQL)
  6. 视图更新法则
    所有理论上可以更新的视图也可以由系统更新。
  7. 高级的插入、更新和删除操作
    把一个基础关系或派生关系作为单个操作对象处理的能力不仅适应于数据的检索,还适用于数据的插入、修改个删除,即在插入、修改和删除操作中数据行被视作集合。
  8. 数据的物理独立性
    不管数据库的数据在存储表示或访问方式上怎么变化,应用程序和终端活动都保持着逻辑上的不变性。
  9. 数据的逻辑独立性
    当对表做了理论上不会损害信息的改变时,应用程序和终端活动都会保持逻辑上的不变性。
  10. 数据完整性的独立性
    专用于某个关系型数据库的完整性约束必须可以用关系数据库子语言定义,而且可以存储在数据目录中,而非程序中。
  11. 分布独立性
    不管数据在物理是否分布式存储,或者任何时候改变分布策略,RDBMS的数据操纵子语言必须能使应用程序和终端活动保持逻辑上的不变性。
  12. 非破坏性法则
    如果一个关系数据库系统支持某种低级(一次处理单个记录)语言,那么这个低级语言不能违反或绕过更高级语言(一次处理多个记录)规定的完整性法则或约束,即用户不能以任何方式违反数据库的约束。

 

还有一些经验:

  • 降低对数据库功能的依赖
    功能应该由程序实现,而非DB实现。原因在于,如果功能由DB实现时,一旦更换的DBMS不如之前的系统强大,不能实现某些功能,这时我们将不得不去修改代码。所以,为了杜绝此类情况的发生,功能应该有程序实现,数据库仅仅负责数据的存储,以达到最低的耦合。
  • 定义实体关系的原则
    当定义一个实体与其他实体之间的关系时,需要考量如下:
    • 牵涉到的实体 识别出关系所涉及的所有实体。
    • 所有权 考虑一个实体“拥有”另一个实体的情况。
    • 基数 考量一个实体的实例和另一个实体实例关联的数量。



From the network data collection and integration, we want to help your software development. Other articles that might interest you:
the performance of enterprise applications in real-time measurement systems evolve
cloud computing reference architecture a few
smart mobile solution brief tour
of human resource management system evolution

If want to know more software, systems, IT, enterprise information, please pay attention to my micro-channel subscription number:

MegadotnetMicroMsg_thumb1_thumb1_thu[1]


Author: Petter Liu
Source: http://www.cnblogs.com/wintersun/
This article belongs to the author and blog Park total, welcome to reprint, but without the author's consent declared by this section must be retained, and given the apparent position of the original article page connection, otherwise the right to pursue legal responsibilities.
The article also posted on my blog, independent - Petter Liu Blog .

Original Address: https: //www.cnblogs.com/wintersun/p/4638176.html

Guess you like

Origin www.cnblogs.com/jpfss/p/11120125.html