表设计是每一个后端程序员都无法避开的一块转,而且这块砖一不小心就很容易烫手,本篇笔记就是喂了帮助大家在设计表是能够轻松拿捏
数据库表名、字段名、索引名等都需要命名规范。命名可读性要高,尽量使用英文,采用驼峰或者下划线分割的方式,让人见名知意。
反例:这些命名过于简单,缺乏描述性,很难让人理解它的含义。
css 体验AI代码助手 代码解读复制代码 表名:a、b、c
字段名:aaa、bbb、ccc
索引名:index1、index2、index3
正例:这些命令就让人见名知意
体验AI代码助手 代码解读复制代码 表名:customers、orders、products
字段名:customer_id、order_date、product_name
索引名:idx_customer_id、inx_order_date
Tips:
设计表时,需要选择合适字段类型,比如说:
主键的设计在数据库中非常重要,它用于唯一标识表中的每一行数据,并且在数据操作和查询中起到关键作用。通常主键的设计,不要与业务相关联,因为业务是会发生变化的,应当使用自增的id,并且保持主键的连续性。比如说可以使用优化的雪花id等等。
首选问大家一个问题,数据库字段长度表示字符长度还是字节长度?
在mysql中,varchar和char类型表示字符长度,而其他类型表示的长度都表示字节长度。
char(10)表示字符长度是10.
bigint(4)表示显示长度是4个字节,但是因为bigint实际长度是8个字节,所以bigint(4)的实际长度就是8个字节。
所以在设计表时需要充分考虑一个字段的长度,比如一个用户名字段(它的长度是5~20个字符),你觉得应该设置多长呢?可以考虑设置为varchar(32)。需要注意字段长度一般设置为2的n次方。
什么是物理删除?什么是逻辑删除?
为什么推荐用逻辑删除,不推荐物理删除呢?
建表的时间一张表的字段不要太多了。尽量不超过20个。超出的话优先考虑拆分,也就是通常的查询表,详情表。
如果没有特殊的理由,一般都建议将字段定义为NOT NULL。为什么呢?
如果将字段默认设置成一个空字符串或常量值并没有什么不同,且都不会影响到应用逻辑,那就可以将这个字段设计为NOT NULL。
当设计表时,需要考虑哪些字段需要加索引,可以遵循以下几个原则:
假设你有一个订单表,包含订单ID、用户ID、订单金额、订单状态等字段。现在需要根据用户ID和订单状态进行查询,可以考虑为用户ID和订单状态这两个字段建立联合索引,例如:
sql 体验AI代码助手 代码解读复制代码 CREATE TABLE order_tab (
id int(11) NOT NULL AUTO_INCREMENT,
user_id int(11) NOT NULL,
amount decimal(10,2) NOT NULL,
status varchar(20) NOT NULL,
create_time datetime NOT NULL,
PRIMARY KEY (id),
KEY idx_user_status(user_id,status) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
简单来说就是反范式设计。常见形式是在第三范式(3NF)的基础上,进一步冗余,从而减少表关联。
回顾下什么事数据库三范式(3NF)?
假设需要设计一个产品订单表,包含以下字段:订单ID、用户ID、订单日期、产品名称、产品价格、产品数量以及订单总价。正常情况下,可能会分别设计订单表和产品表,并使用外键进行关联,例如:
sql 体验AI代码助手 代码解读复制代码 CREATE TABLE order (
id int(11) NOT NULL AUTO_INCREMENT,
user_id int(11) NOT NULL,
order_date date NOT NULL,
product_id int(11) NOT NULL,
quantity int(11) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (product_id) REFERENCES product (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE order (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
price decimal(10,2) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
这个设计方式符合范式要求,但在查询时需要进行表关联操作,可能会降低查询效率。为了提高查询效率,我们可以使用反范式的设计方式,将订单表中的产品名称、产品价格和订单总价冗余存储到订单表中,从而避免关联查询。例如:
sql 体验AI代码助手 代码解读复制代码 CREATE TABLE order (
id int(11) NOT NULL AUTO_INCREMENT,
user_id int(11) NOT NULL,
order_date date NOT NULL,
product_name varchar(255) NOT NULL,
product_price decimal(10,2) NOT NULL,
quantity int(11) NOT NULL,
total_price decimal(10,2) NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
通过这种反范式的设计方式,我们可以避免表关联操作,提高查询效率。但同时也带来了一些缺点,例如数据冗余、数据更新困难等。因此,在实际应用中需要根据具体情况进行选择。
如果库名、表名、字段名等属性含有保留字时,SQL语句必须用反引号来引用属性名称,这将使得SQL语句书写、SHELL脚本中变量的转义等变得非常复杂。
如果你需要使用这些保留字作为表名、列名或其他标识符,你可以考虑以下方法来避免冲突:
my_table
,列名命名为column_name
。orders_table
,列名命名为order_status
。table
,列名命名为column
。请注意,在使用反引号时要小心,确保使用正确的语法和规范。常见保留字:
sql 体验AI代码助手 代码解读复制代码 ADD
ALL
ALTER
AND
AS
BETWEEN
BY
CASE
DELETE
FROM
GROUP
HAVING
INSERT
在数据库设计中,使用外键关联是一种良好的实践,可以确保数据的完整性和一致性。外键关联可以帮助维护表之间的关系,防止无效或不一致的数据插入、更新或删除操作。然而,在某些情况下,也存在一些缺点,这可能是导致现在不太推荐使用外键关联的原因之一。以下是一些这种情况:
因此,在决定是否使用外键关联的,需要考虑实际业务需求和场景,并进行权衡和决策。在某些情况下,可以采用其他方法来保证数据的完整性和一致性,例如使用应用程序逻辑或数据库触发器来实现约束检查和数据操作。同时,需要注意数据库设计的基本原则和最佳实践,例如避免数据冗余、遵循规范化原则和正常化理论等。
设计表时每个字段的含义要注释清楚,包括枚举类型。比如说:
sql 体验AI代码助手 代码解读复制代码 order_status varchar(2) COLLATE utf8_bin NOT NULL COMMIT '订单状态 01:待支付 02:已支付 03:已发货 04:已完成 05:已取消'
时间类型的选择一般都要好好考虑,因为不同的类型存储的格式不同。
对于MySQL来说,主要有date、datetime、time、timestamp和year。
推荐优先使用datetime类型来保存日期和时间,因为存储范围更大,且跟时区无关。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。