数据库表结构设计,常见的数据库管理系统

数据库表结构设计,常见的数据库管理系统,第1张

一、数据场景 1、表结构简介 任何工具类的东西都是为了解决某个场景下的问题,比如Redis缓存系统热点数据,ClickHouse解决海量数据的实时分析,MySQL关系型数据库存储结构化数据。数据的存储则需要设计对应的表结构,清楚的表结构,有助于快速开发业务,和理解系统。表结构的设计通常从下面几个方面考虑:业务场景、设计规范、表结构、字段属性、数据管理。

2、用户场景

例如存储用户基础信息数据,通常都会下面几个相关表结构:用户信息表、单点登录表、状态管理表、支付账户表等。

用户信息表

存储用户三要素相关信息:姓名,手机号,身份z,登录密码,邮箱等。

CREATE TABLE `ms_user_center` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', `user_name` varchar(20) NOT NULL COMMENT '用户名', `real_name` varchar(20) DEFAULT NULL COMMENT '真实姓名', `pass_word` varchar(32) NOT NULL COMMENT '密码', `phone` varchar(20) NOT NULL COMMENT '手机号', `email` varchar(32) DEFAULT NULL COMMENT '邮箱', `head_url` varchar(100) DEFAULT NULL COMMENT '用户头像URL', `card_id` varchar(32) DEFAULT NULL COMMENT '身份z号', `user_sex` int(1) DEFAULT '1' COMMENT '用户性别:0-女,1-男', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表'; 单点登录表

用意是在多个业务系统中,用户登录一次就可以访问所有相互信任的业务子系统,是聚合业务平台常用的解决方案。

CREATE TABLE `ms_user_sso` ( `user_id` int(11) NOT NULL COMMENT '用户ID', `sso_id` varchar(32) NOT NULL COMMENT '单点信息编号ID', `sso_code` varchar(32) NOT NULL COMMENT '单点登录码,唯一核心标识', `log_ip` varchar(32) DEFAULT NULL COMMENT '登录IP地址', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户单点登录表'; 状态管理表

系统用户在使用时候可能出现多个状态,例如账户冻结、密码锁定等,把状态聚合到一起,可以更加方便的管理和验证。

CREATE TABLE `ms_user_status` ( `user_id` int(11) NOT NULL COMMENT '用户ID', `account_status` int(1) DEFAULT '1' COMMENT '账户状态:0-冻结,1-未冻结', `real_name_status` int(1) DEFAULT '0' COMMENT '实名认证状态:0-未实名,1-已实名', `pay_pass_status` int(1) DEFAULT '0' COMMENT '支付密码是否设置:0-未设置,1-设置', `wallet_pass_status` int(1) DEFAULT '0' COMMENT '钱包密码是否设置:0-未设置,1-设置', `wallet_status` int(1) DEFAULT '1' COMMENT '钱包是否冻结:0-冻结,1-未冻结', `email_status` int(1) DEFAULT '0' COMMENT '邮箱状态:0-未激活,1-激活', `message_status` int(1) DEFAULT '1' COMMENT '短信提醒开启:0-未开启,1-开启', `letter_status` int(1) DEFAULT '1' COMMENT '站内信提醒开启:0-未开启,1-开启', `emailmsg_status` int(1) DEFAULT '0' COMMENT '邮件提醒开启:0-未开启,1-开启', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`user_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户状态表'; 支付账户表

用户交易的核心表,存储用户相关的账户资金信息。

CREATE TABLE `ms_user_wallet` ( `wallet_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '钱包ID', `user_id` int(11) NOT NULL COMMENT '用户ID', `wallet_pwd` varchar(32) DEFAULT NULL COMMENT '钱包密码', `total_account` decimal(20,2) DEFAULT '000' COMMENT '账户总额', `usable_money` decimal(20,2) DEFAULT '000' COMMENT '可用余额', `freeze_money` decimal(20,2) DEFAULT '000' COMMENT '冻结金额', `freeze_time` datetime DEFAULT NULL COMMENT '冻结时间', `thaw_time` datetime DEFAULT NULL COMMENT '解冻时间', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', `state` int(1) DEFAULT '1' COMMENT '是否可用,0-不可用,1-可用', PRIMARY KEY (`wallet_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户钱包'; 二、设计规范 1、涉及模块

通过上面几个表设计的案例,可以看到表设计关联到数据库的各个方面知识:数据类型,索引,编码,存储引擎等。表设计是一个很大的命题,不过也遵循一个基本规范:三范式。

2、三范式 基础概念

一范式

表的列的具有原子性,不可再分解,即列的信息,不能分解,关系型数据库MySQL、Oracle等自动的满足。

二范式

每个事实的数据记录只会出现一次, 不会冗余, 通常设计一个主键来实现。

三范式

要求一个表中不包含已经存在于其它表的非主键信息,例如部门和员工的信息,员工表包含部门表的主键ID,则可以关联获取相关信息,没必要在员工表保存相关信息。

优缺点对比

范式化设计

范式化结构设计通常更新快,因为冗余数据较少,表结构轻巧,也更好的写入内存中。但是查询起来涉及到关联,代价非常高,非常损耗查询性能。

反范式化设计

所有的数据都在一张表中,避免关联查询,索引的有效性更高,但是数据的冗余性极高。

建议结论

上述的两种设计方式在实际开发中都是不存在的,在实际开发中都是混合使用。比如汇总统计,缓存数据,都会基于反范式化的设计。

三、字段属性

合适的字段类型对于高性能来说非常重要,基本原则如下:简单的类型占用资源更少;在可以正确存储数据的情况下,选最小的数据类型。

1、数据类型选择 整数类型

TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT,根据数据类型范围合理选择即可。

实数类型

FLOAT、DOUBLE、DECIMAL,建议资金货币相关类型使用高精度DECIMAL存储,或者把数据成倍扩大为整数,采用BIGINT存储,不过处理相对麻烦。

字符类型

CHAR、VARCHAR,长度不确定建议采用VARCHAR存储,不过VARCHAR类型需要额外开销记录字符串长度。CHAR适合存储短字符,或者定长字符串,例如MD5的加密结构。

时间类型

DATETIME、TIMESTAMP,DATETIME保存大范围的值,精度秒。TIMESTAMP以时间戳的格式,范围相对较小,效率也相对较高,所以通常情况建议使用。

MySQL的字段类型有很多种,可以根据数据特性选择合适的,这里只描述常见的几种类型。

2、基础用法 *** 作 数据类型

修改字段类型

ALTER TABLE ms_user_sso MODIFY state CHAR(1) DEFAULT '0' ; ALTER TABLE ms_user_sso MODIFY state INT(1) DEFAULT '1' COMMENT '状态:0不可用,1可用';

修改名称位置

ALTER TABLE ms_user_sso CHANGE log_ip login_ip VARCHAR(32) AFTER update_time ; 索引使用

索引类型:主键索引,普通索引,唯一索引,组合索引,全文索引。这里演示普通索引的 *** 作。MySQL的核心模块,后续详说。

添加索引

ALTER TABLE ms_user_wallet ADD INDEX user_id_index(user_id) ; CREATE INDEX state_index ON ms_user_wallet(state) ;

查看索引

SHOW INDEX FROM ms_user_wallet;

删除索引

DROP INDEX state_index ON ms_user_wallet ;

修改索引

不具有真正意义上的修改,可以把原有的索引删除之后,再次添加索引。

外键关联

用处:外键关联的作用保证多个数据表的数据一致性和完整性,建表时先有主表,后有从表;删除数据表,需要先删从表,再删主表。复杂场景不建议使用,实际开发中用的也不多。

添加外键

ALTER TABLE ms_user_wallet ADD CONSTRAINT user_id_out_key FOREIGN KEY(user_id) REFERENCES ms_user_center(id) ;

删除外键

ALTER TABLE ms_user_wallet DROP FOREIGN KEY user_id_out_key ; 四、表结构管理 1、查看结构 DESC ms_user_status ; SHOW CREATE TABLE ms_user_status ; 2、字段结构 添加字段 ALTER TABLE ms_user_status ADD `delete_time` datetime DEFAULT NULL COMMENT '删除时间' ; 删除字段 ALTER TABLE ms_user_status DROP COLUMN delete_time ; 3、修改表名 ALTER TABLE ms_user_center RENAME ms_user_info ; 4、存储引擎 存储引擎 SELECT VERSION() ; SHOW ENGINES ;

MySQL 56 支持的存储引擎有InnoDB、MyISAM、Memory、Archive、CSV、BLACKHOLE等。一般默认使用InnoDB,支持事务管理。该模块MySQL核心,后续详解。

修改引擎

数据量大的场景下,存储引擎修改是一个难度极大的 *** 作,容易会导致表的特性变动,引起各种后续反应,后续会详说。

ALTER TABLE ms_user_sso ENGINE = MyISAM ; 5、修改编码

表字符集默认使用utf8,通用,无乱码风险,汉字3字节,英文1字节,utf8mb4是utf8的超集,有存储4字节例如表情符号时使用。

查看编码 SHOW VARIABLES LIKE 'character%'; 修改编码 ALTER TABLE ms_user_sso DEFAULT CHARACTER SET utf8mb4; 五、数据管理 1、增删改查

添加数据

INSERT INTO ms_user_sso ( user_id,sso_id,sso_code,create_time,update_time,login_ip,state ) VALUES ( '1','SSO7637267','SSO78631273612', '2019-12-24 11:56:57','2019-12-24 11:57:01','127001','1' );

更新数据

UPDATE ms_user_sso SET user_id = '1',sso_id = 'SSO20191224',sso_code = 'SSO20191224', create_time = '2019-11-24 11:56:57',update_time = '2019-11-24 11:57:01', login_ip = '127001',state = '1' WHERE user_id = '1';

查询数据

一般情况下都是禁止使用 select *** 作。

SELECT user_id,sso_id,sso_code,create_time,update_time,login_ip,state FROM ms_user_sso WHERE user_id = '1';

删除数据

DELETE FROM ms_user_sso WHERE user_id = '2' ;

不带where条件,就是删除全部数据。原则上不允许该 *** 作,优化篇会详解。TRUNCATE TABLE也是清空表数据,但是占用的资源相对较少。

2、数据安全 不可逆加密

这类加密算法,多用来做数据验证 *** 作,比如常见的密码验证。

SELECT MD5('cicada')='94454b1241ad2cfbd0c44efda1b6b6ba' ; SELECT SHA('cicada')='0501746a2e4fd34e1d14015fc4d58309585edc7d'; SELECT PASSWORD('smile')='B4FB95D86DCFC3F33A3852714DC742C77504479D' ; 可逆加密

安全性要求高的系统,需要做三级等保,对数据的安全性极高,数据在存储时必须加密入库,取出时候需要解密,这些就需要可逆加密。

SELECT DECODE(ENCODE('123456','key_salt'),'key_salt') ; SELECT AES_DECRYPT(AES_ENCRYPT('cicada','salt123'),'salt123');

上述数据安全的管理,也可以基于应用系统的服务(代码)层进行处理,相对专业的流程是从数据生成源头处理,规避数据传递过程泄露,造成不必要的风险。

1、建立公司表

id1 name

2、建立部门表

id2 name

3、建立岗位表

id3 name

4、建立公司 部门映射表

id4 companyId departmentId

表示每个companyId(id1)公司下都有哪些部门departmentId(od2)

4、建立公司 部门映射表

id4 jobid

表示每个部门映射表Id下都有哪些岗位

员工基本信息表(包括姓名、年月等基本信息)

公司职务表(公司所设职务名称、说明、职务类别等)

岗位表(岗位名称、说明、所属部门等)

部门列表(部门名称、类别、上级部门id)

部门员工清单(部门id、员工信息表id、岗位id等)

其实这些表可以归纳为一个表:

员工信息表(包括姓名、日期、职务名称、说明、职务类别、岗位名称、部门名称、类别、上级部门id等基本信息)

哈哈!条件查询修改就不的了????

在oracle数据库中,列出部门名称和这些部门的雇员,同时列出那些没有雇员的部门

那就要用连接表了。

SELECT DEPT,EMP FROM DEPT LEFT JOIN EMP ON DEPTD_NO=EMPD_NO;

还有种简写形式,

SELECT DEPT,EMP FROM DEPT,EMP WHERE EMPD_NO(+)=DEPTD_NO;

1、设有数据表“pay”(考VFP的同学请下载{<paydbf>};考ACCESS的同学请下载{<laboragemdb>}),包含以下字段:工号(C)、姓名(C)、性别(C)、部门(C)、婚否(L)、工作日期(D)、工资(N)、补贴(N)、公积金(N),应发工资(N)。(填写命令时,均不考虑表的打开和关闭。)

要求填写VFP或SQL命令,列出部门为“研发部”的男性职工的工号,姓名,性别和部门。

SELECT pay工号, pay姓名, pay性别, pay部门

FROM pay

WHERE (((pay性别)="男") AND ((pay部门)="研发部"));

2、统计“研发部”和“办公室”这两个部门职工的工资总和、补贴总和,并将结果赋给变量A5101、A5102(或者新字段A5101、A5102)。

SELECT Sum([工资]) AS a5101, Sum([补贴]) AS a5102

FROM pay

WHERE (((pay部门)="研发部" Or (pay部门)="办公室"));

3、统计男性职工中补贴一项的最高值,并将结果赋给变量A57(或者新字段A57)。

SELECT Max([补贴]) AS a57

FROM pay

WHERE (((pay性别)="男"));

4、计算并替换每一条记录中的“应发工资”字段(应发工资=工资+补贴-公积金)。

UPDATE pay SET pay应发工资 = [pay][工资]+[pay][补贴]-[pay][公积金];

5、列出工号前2位等于“02”的女性职工的信息。

SELECT pay

FROM pay

WHERE (((Left([pay][工号],2))="02") AND ((pay性别)="女"));

6、为8月份参加工作的职工每人增加55元补贴。

UPDATE pay SET pay补贴 = [pay][补贴]+55

WHERE (((Month([工作日期]))=8));

7、统计“财务科”和“办公室”这两个部门职工的平均工资和平均补贴,并将结果赋给变量A591和A592(或者新字段A591和A592)。

SELECT Avg([工资]) AS a591, Avg([补贴]) AS a592

FROM pay

WHERE (((pay部门)="财务科" Or (pay部门)="办公室"));

8、统计部门为“研发部”的女性职工的工资字段平均值,并将结果赋给变量A53(或者新字段A53)。

SELECT Avg([工资]) AS a53

FROM pay

WHERE (((pay部门)="研发部") AND ((pay性别)="女"));

9、为部门是“研发部”的职工每人增加25%的补贴(补贴=补贴125)。

UPDATE pay SET pay补贴 = [pay][补贴]125

WHERE (((pay部门)="研发部"));

10、列出工资大于1800元的男性职工的工号、姓名、性别、部门和工资。

SELECT pay工号, pay姓名, pay性别, pay部门, pay工资

FROM pay

WHERE (((pay性别)="男") AND ((pay工资)>1800));

11、统计女性职工中工资不超过1800元的人数,并将结果赋给变量A56(或者新字段A56)。

SELECT Count([姓名]) AS a56

FROM pay

WHERE (((pay性别)="女") AND ((pay工资)<=1800));

12、在“工资”字段中,为2000年以前(不含2000年)参加工作的职工每人增加270元。

UPDATE pay SET pay工资 = [pay][工资]+270

WHERE (((Year([工作日期]))<2000));

13、计算并替换每一条记录中的“公积金”字段(公积金=工资005)。

UPDATE pay SET pay公积金 = [pay][工资]005;

14、统计部门为“财务科”的女性职工的工资字段总和,并将结果赋给变量A51(或者新字段A51)。

SELECT Sum([工资]) AS a51

FROM pay

WHERE (((pay部门)="财务科") AND ((pay性别)="女"));

15、统计男性已婚职工的工资字段平均值,并将结果赋给变量A54(或者新字段A54)。

SELECT Avg([工资]) AS a54

FROM pay

WHERE (((pay婚否)=True) AND ((pay性别)="男"));

16、统计男性职工中工资超过2000元的人数,并将结果赋给变量A55(或者新字段A55)。

SELECT Count([姓名]) AS a55

FROM pay

WHERE (((pay性别)="男") AND ((pay工资)>2000));

17、列出部门为“财务科”和“研发部”的所有女性职工的信息。

SELECT pay

FROM pay

WHERE (((pay性别)="女") AND (((pay部门)="财务科") OR ((pay部门)="研发部")));

18、统计男性已婚职工的工资字段总和,并将结果赋给变量A52(或者新字段A52)。

SELECT Sum([工资]) AS a52

FROM pay

WHERE (((pay婚否)=True) AND ((pay性别)="男"));

19、将工号前4位是“0202”的职工所属部门改为“出纳科”。

UPDATE pay SET pay部门 = "出纳科"

WHERE (((Left([工号],4))="0202"));

20、列出工号前2位等于“01”的男性职工的信息。

SELECT pay

FROM pay

WHERE (((Left([pay][工号],2))="01") AND ((pay性别)="男"));

21、列出工资小2000元的女性职工的工号、姓名、性别、部门和工资。

SELECT pay工号, pay姓名, pay性别, pay部门, pay工资

FROM pay

WHERE (((pay性别)="女") AND ((pay工资)<2000));

22、为6月份参加工作的职工每人增加38元补贴。

UPDATE pay SET pay补贴 = [pay][补贴]+38

WHERE (((Month([工作日期]))=6));

23、列出所有已婚男性职工的部门、姓名、婚否和工资。

SELECT pay部门, pay姓名, pay婚否, pay工资

FROM pay

WHERE (((pay婚否)=True) AND ((pay性别)="男"));

24、列出部门为“财务科”的女性职工的工号,姓名,性别和部门。

SELECT pay工号, pay姓名, pay性别, pay部门

FROM pay

WHERE (((pay性别)="女") AND ((pay部门)="财务科"));

25、将工号前4位是“0102”的职工所属部门改为“秘书科”。

UPDATE pay SET pay部门 = "秘书科"

WHERE (((Left([工号],4))="0102"));

以上就是关于数据库表结构设计,常见的数据库管理系统全部的内容,包括:数据库表结构设计,常见的数据库管理系统、SQLServer数据库建表思路以及示范、人事管理数据库表设计等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9867204.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存