数据库分表设计-任我行

本文只阐述一个完整的实例,直接可以复制过去用,不作过多的解释。

简单说一下分表与分区:

分区的原理:我在深圳市,但我也在中国,如果中国没有划分区域的话,搜索范围将是整个中国,查询起来很费力。现在既然中国已经划分区域当然可以直接来深圳市找我了,是不是快了很多。

分表的原理:我在中国,通过某种算法(比如查户口)知道了我在深圳,是不是也可以直接来深圳市找我,其他区域就不用去看了,本文的算法为dbo.GetTableName(),通过这个算法知道了数据存储在哪张表里面。

--用于保存所有日志ID,与操作项的Id,在操作日志的时候,
--可以依据此表来获取最后一次日志插入的ID,依据此ID来决定插入日志子表
CREATE TABLE LogId
(
    Id INT IDENTITY(1,1) PRIMARY KEY,
    ItemId int
)

GO

--创建日志表,共创建8张表
CREATE TABLE Logs_0
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_1
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_2
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_3
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_4
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_5
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_6
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_7
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
)
GO
CREATE TABLE Logs_8
(
    LogId INT PRIMARY KEY,
    LogType NVARCHAR(100),--日志类型
    Operator NVARCHAR(100),--操作者
    ItemId INT,--操作项主键
    [Description] NVARCHAR(2000),--操作描述
    OperateDate DATETIME,--操作日期
    OperateIP NVARCHAR(50)--操作IP
);

GO
--创建视图,关联起所有的日志子表,查询时直接操作此视图
CREATE VIEW Logs
AS
    SELECT *  FROM dbo.Logs_0 UNION ALL
    SELECT *  FROM dbo.Logs_1 UNION ALL
    SELECT *  FROM dbo.Logs_2 UNION ALL
    SELECT *  FROM dbo.Logs_3 UNION ALL
    SELECT *  FROM dbo.Logs_4 UNION ALL
    SELECT *  FROM dbo.Logs_5 UNION ALL
    SELECT *  FROM dbo.Logs_6 UNION ALL
    SELECT *  FROM dbo.Logs_7 UNION ALL
    SELECT *  FROM dbo.Logs_8
GO
--根据dbo.LogId最后一次插入的Id值来确定到底需要插入到哪张日志子表,并返回表名
CREATE FUNCTION [dbo].[GetTableName](
@Id INT,
@table NVARCHAR(50)=‘Logs‘)
RETURNS NVARCHAR(60)
AS
BEGIN
    DECLARE @tablename NVARCHAR(60)
    DECLARE @tableId INT, @delimiter INT

    SET @delimiter = 20000        --注意,一旦定下,不可再修改,因项目而异,可以更大小,建议不要超过50W
    SET @tableId = FLOOR(@Id/@delimiter)
    SET @tablename = ‘dbo.‘ + @table + ‘_‘ + CAST(@tableId AS nvarchar)

    RETURN @tablename

    RETURN ‘‘;
END
GO
--添加日志
CREATE PROC [dbo].[LogAdd]
@logid int,
@logtype nvarchar(100),
@operator nvarchar(100),
@itemid int,
@description nvarchar(2000),
@operatedate datetime,
@operateip nvarchar(50)

as

    declare @tablename nvarchar(100) = ‘Logs‘,@sql nvarchar(1000) = ‘‘

    insert LogId(ItemId)values(@itemid)
    set @logid = @@IDENTITY

    set @tablename = dbo.GetTableName(@logid, ‘Logs‘)

    set @sql=N‘insert ‘+@tablename+‘(LogId,LogType,[Operator],ItemId,[Description],OperateDate,OperateIP)values(@logid,@logtype,@operator,@itemid,@description,@operatedate,@operateip);SELECT @@IDENTITY‘

    exec sp_executesql @sql,N‘@logid int,@logtype nvarchar(100),@operator nvarchar(100),@itemid int,@description nvarchar(2000),@operatedate datetime,@operateip nvarchar(50)‘
    ,@logid=@logid,@logtype=@logtype,@operator=@operator,@itemid=@itemid,@description=@description,@operatedate=@operatedate,@operateip=@operateip
GO
--修改日志
CREATE PROC [dbo].[LogUpdate]
@logid int,
@logtype nvarchar(100),
@operator nvarchar(100),
@itemid int,
@description nvarchar(2000),
@operatedate datetime,
@operateip nvarchar(50)
as

    declare @tablename nvarchar(100)=‘Logs‘,@sql nvarchar(1000)=‘‘

    set @tablename=dbo.GetTableName(@logid,‘Logs‘)

    set @sql=N‘update ‘+@tablename+‘ set LogType,[Operator],[Description],OperateDate,OperateIP where [email protected];SELECT @@IDENTITY‘

    exec sp_executesql @sql,N‘@logid int,@logtype nvarchar(100),@operator nvarchar(100),@itemid int,@description nvarchar(2000),@operatedate datetime,@operateip nvarchar(50)‘
    ,@logid=@logid,@logtype=@logtype,@operator=@operator,@itemid=@itemid,@description=@description,@operatedate=@operatedate,@operateip=@operateip

GO
--删除日志
CREATE PROC [dbo].[LogDelete]
@logid int
AS
BEGIN
    declare @tablename nvarchar(100)=‘Logs‘,@sql nvarchar(1000)=‘‘

    set @tablename=dbo.GetTableName(@logid,‘Logs‘);
    set @sql=N‘delete ‘+@tablename + ‘ where LogId=‘+@logid;
    exec(@sql);
END
GO
--得到日志查询的总记录数
CREATE PROC [dbo].[LogSearchCount]
@condition NVARCHAR(1000)
AS
    declare @sql nvarchar(2000)=‘‘
    set @sql = ‘select count(0) from Logs where 1=1 ‘+@condition
    exec(@sql);
GO
--查询日志,直接操作Logs视图
CREATE PROC [dbo].[LogSearch]
@begin NVARCHAR(10),
@end NVARCHAR(10),
@condition NVARCHAR(1000)
AS
declare @sql nvarchar(2000)=‘‘
    set @sql =N‘SELECT * FROM (SELECT ROW_NUMBER()OVER(ORDER BY LogId) line,* FROM Logs WHERE 1=1 ‘+@condition+‘ )A WHERE A.line>‘+@begin+‘ AND A.line<=‘+@end;

数据库分表设计-任我行,布布扣,bubuko.com

时间: 2024-10-21 20:35:53

数据库分表设计-任我行的相关文章

数据库分表设计

具体来说就是数据库有这样的表account0account1account2account3 每个表假如说是存1万个玩家sprintf(m_szSql,"UPDATE account%d SET rmcard=rmcard + %lld,coin=coin + %lld,safecoin=safecoin + %lld where uid=%d;",CCommonLogic::GetDataTableNum(uid),roomCard,coin,safecoin,uid); 这是分表的

数据库分表分库

产生原因 1.当数据达到了上亿级别单个库使用效率性能是十分低下的,当进行查询等操作时候,也是从根节点去找到子节点然后在找到叶节点 , 数亿条取一条数据 性能就不是很迅速,而且单机的存储量,链接数,并发量,处理能力十分有限. 这个时候数据库就容易遇到了系统瓶颈, 所以为了 降低性能,缩短查询时间,减少数据库的负担,会采取分表分库的方法 . 数据库分表分库思路:水平拆分和垂直拆分 垂直拆分:就是不同的表存储在不同的数据库,按照业务进行独立划分 ,主要通过'列'进行划分,将不常用的字段或者较大的字段拆

数据库分表和分库的原理及基于thinkPHP的实现方法

为什么要分表,分库: 当我们的数据表数据量,访问量很大,或者是使用频繁的时候,一个数据表已经不能承受如此大的数据访问和存储,所以,为了减轻数据库的负担,加快数据的存储,就需要将一张表分成多张,及将一类数据存入不同的几张表,当分表已经不能满足需求是,我们还可以分库,及用几个数据库存储. 分表会随着需求和功能的不同有不同的实现方法,下面是我做项目中的一个例子: 需求:product,product_price两张表是一对多的关系,及产品和产品每日的价格,一个产品对应几种价格,现在由于产品表数据量很大

MySQL 数据库分表分区

博主QQ:819594300 博客地址:http://zpf666.blog.51cto.com/ 有什么疑问的朋友可以联系博主,博主会帮你们解答,谢谢支持!一.分表 为什么要分表? 我们的数据库数据越来越大,随之而来的是单个表中数据太多.以至于查询书读变慢,而且由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈. 什么是分表? 分表是将一个达标按照一定的规则分解成多张具有独立存储空间的实体表,每个表都对应三个文件,.MYD数据文件..MYI索引文件..frm表结构文件.这些表可以分

mysql数据库分表分区

防伪码:博观而约取,厚积而薄发 为什么要分表和分区? 我们的数据库数据越来越大,随之而来的是单个表中数据太多.以至于查询书读变慢,而且 由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈. mysql 中有一种机制是表锁定和行锁定,是为了保证数据的完整性.表锁定表示你们都不能 对这张表进行操作,必须等我对表操作完才行.行锁定也一样,别的 sql 必须等我对这条数 据操作完了,才能对这条数据进行操作.当出现这种情况时,我们可以考虑分表或分区. 1.分表 什么是分表? 分表是将一个大表按

MySQL数据库分表分表区

为什么要分表和分区? 我们的数据库数据越来越大,随之而来的是单个表中数据太多.以至于查询书读变慢,而且由于表的锁机制导致应用操作也搜到严重影响,出现了数据库性能瓶颈. mysql中有一种机制是表锁定和行锁定,是为了保证数据的完整性.表锁定表示你们都不能对这张表进行操作,必须等我对表操作完才行.行锁定也一样,别的sql必须等我对这条数据操作完了,才能对这条数据进行操作.当出现这种情况时,我们可以考虑分表或分区. 1.分表 什么是分表? 分表是将一个大表按照一定的规则分解成多张具有独立存储空间的实体

Mycat(4):消息表mysql数据库分表实践

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/46882777 未经博主允许不得转载. 1,业务需求 比如一个社交软件,比如像腾讯的qq.可以进行群聊天(gid),也可以单人聊天. 这里面使用到了数据库中间件mycat,和mysql数据表分区. 关于mycat分区参考: [ 数据库垂直拆分,水平拆分利器,cobar升级版mycat] http://blog.csdn.net/freewebsys/article/details

MySQL数据库分表分区(一)(转)

面对当今大数据存储,设想当mysql中一个表的总记录超过1000W,会出现性能的大幅度下降吗? 答案是肯定的,一个表的总记录超过1000W,在操作系统层面检索也是效率非常低的 解决方案: 目前针对海量数据的优化有两种方法: 1.大表拆小表的方式(主要有分表和分区两者技术) (1)分表技术 垂直分割 优势:降低高并发情况下,对于表的锁定. 不足:对于单表来说,随着数据库的记录增多,读写压力将进一步增大. 水平分割 如果单表的IO压力大,可以考虑用水平分割,其原理就是通过hash算法,将一张表分为N

架构之数据库分表分库

1 基本思想之什么是分库分表?从字面上简单理解,就是把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上.2 基本思想之为什么要分库分表? 数据库中的数据量不一定是可控的,在未进行分库分表的情况下,随着时间和业务的发展,库中的表会越来越多,表中的数据量也会越来越大,相应地,数据操作,增删改查的开销也会越来越大:另外,由于无法进行分布式式部署,而一台服务器的资源(CPU.磁盘.内存.IO等)是有限的,最终数据库所能承载的数据量.数据处理能力都将遭遇瓶颈.3 分库分