如何减少在创建库表结构时,频繁去添加字段的问题?

目录

先思考数据库建表三大范式

数据库表三大范式

第一范式

第二范式

第三范式

场景描述

遵循第三范式的设计

违反第三范式的设计

对设计出的表字段进行适当的冗余,用空间换时间。

增加对业务的了解程度,多方了解,提前进行确认

适时使用拓展字段


先思考数据库建表三大范式

对照需求或者原型图进行基础表字段设计,参考数据库表三大范式

数据库表三大范式

数据库有8种范式(Normal Form),通常只用到前3种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF),我们设计的关系数据库要满足这3种范式。

第一范式

1NF是对属性的原子性约束,要求属性具有原子性,不可再分解。

第二范式

2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性。表中的每一条记录都要是可区分的,表中必须要有一个unique字段作为主键。

第二范式建立在第一范式的基础上,满足第二范式必须要先满足第一范式。

第三范式

3NF是对字段冗余性的约束,要求属性不能有依赖传递(只依赖于主键,不依赖于主键之外的其它属性),简单来说就是要求没有冗余字段。

第三范式建立在第二范式的基础上,满足第三范式需要先满足第二范式。

范式、冗余的取舍:有时为了提高效率,可以适当违反第三范式,冗余部分字段以减少多表查询,用空间换时间。

场景描述

假设有一个电商系统,包含订单表 Orders 和用户表 Users。在严格遵循第三范式的情况下,订单表只存储 用户ID,需要通过联表查询获取用户的详细信息。

遵循第三范式的设计

  • 用户表 Users

用户ID

用户姓名

用户地址

U01

张三

北京市

U02

李四

上海市

  • 订单表 Orders

订单ID

用户ID

订单日期

总金额

1001

U01

2023-10-01

500元

1002

U02

2023-10-02

300元

在这种设计下,每次查询订单信息时,都需要通过联表查询获取用户的详细信息,这在高并发、大数据量的情况下会增加查询时间和系统负载。

违反第三范式的设计

为了提高查询性能,可以在订单表中冗余存储 用户姓名用户地址 等信息,这样查询订单信息时无需联表查询 Users 表,从而提升查询速度。

  • 用户表 Users

用户ID

用户姓名

用户地址

U01

张三

北京市

U02

李四

上海市

  • 订单表 Orders

订单ID

用户ID

用户姓名

用户地址

订单日期

总金额

1001

U01

张三

北京市

2023-10-01

500元

1002

U02

李四

上海市

2023-10-02

300元

对设计出的表字段进行适当的冗余,用空间换时间。

数据库三大范式的形成是由于在早期计算机系统中,存储资源(如磁盘空间)非常有限且昂贵。因此,减少数据冗余不仅可以节省存储空间,还能降低存储成本。这种需求促使数据库设计者努力优化数据存储结构,以确保数据的高效存储和管理。

但是现在随着关系数据库理论的成熟和范式理论的出现,技术的逐渐成熟,存储成本逐渐降低,而性能优化成为更重要的考虑。范式化设计通过减少冗余,降低了数据存储量,从而提高了查询和更新操作的效率。此外,范式化设计还通过规范化表结构,使得数据库更容易维护和扩展。

由第三范式中引申出来的问题,需要对设计出的表字段进行适当的冗余,以减少多表查询,用空间换时间。这点需要在长期多次对库表进行设计或者对对应的业务逻辑更加了解,才会知道哪些字段做成冗余字段,会更好的减少多表查询的工作量。

增加对业务的了解程度,多方了解,提前进行确认

简而言之,就是提前对业务进行了解和询问,提前与售前等人员进行沟通,或者在进行开发时,即使进行反馈和确认,减少后期因为返工带来的重复性工作。

适时使用拓展字段

扩展字段一般用于存储一些不太关键但是有需要存储的数据,一般不用于查询条件,仅用于展示用。这些字段可能有很多,一般我们直接存储成json。如果真的需要添加一些仅用于展示用的字段,而没有深入业务逻辑的字段,则可以在拓展字段中添加,但如果需要添加与业务逻辑强绑定的字段,还是需要添加,而不是写入拓展字段中。

在 MySQL 中为添加索引是一个非常重要的数据库优化手段,尤其是在频繁查询的字段上。下面我将详细回答你的问题。 --- ### ✅ 如何在 MySQL 中为添加索引? #### 1. **创建普通索引(INDEX)** 你可以使用 `CREATE INDEX` 或 `ALTER TABLE` 语句来为 `name` 字段添加索引。 ```sql -- 方法一:使用 CREATE INDEX(推荐用于只索引) CREATE INDEX idx_employee_name ON employee(name); ``` ```sql -- 方法二:使用 ALTER TABLE ALTER TABLE employee ADD INDEX idx_employee_name (name); ``` > **说明:** > - `idx_employee_name` 是你给索引起的名字,建议命名规范清晰,便于维护。 > - `(name)` 示对 `name` 字段建立索引。 > - 如果字段长度较长(如 VARCHAR(100)),也可以只对前 N 个字符建索引,例如: > ```sql > CREATE INDEX idx_employee_name ON employee(name(20)); > ``` > 这示只对 `name` 的前 20 个字符建立索引,节省空间并提高性能。 --- #### 2. **查看索引是否创建成功** ```sql SHOW INDEX FROM employee; ``` 这会列出 `employee` 的所有索引信息,包括主键、唯一索引和普通索引。 --- #### 3. **删除索引(如果需要)** ```sql DROP INDEX idx_employee_name ON employee; ``` --- ### ✅ 为什么要为 `name` 字段添加索引? 当你经常根据 `name` 字段进行查询、更新或删除操作(比如 `WHERE name = 'John Doe'`),MySQL 需要扫描整张来查找匹配的行 —— 这叫做**全扫描(Full Table Scan)**,效率很低。 #### 添加索引的好处: | 优势 | 说明 | |------|------| | 🔍 **快查询速度** | 索引类似于书籍的目录,可以让 MySQL 快速定位到目标数据,避免全扫描。 | | 📈 **提升 UPDATE 和 DELETE 性能** | 当你执行 `UPDATE employee SET ... WHERE name='John Doe'` ,MySQL 也需要先找到这条记录。有索引就能更快定位。 | | ⚡ **适用于高频查询字段** | 如果 `name` 经常作为查询条件(如登录、搜索员工),索引非常必要。 | --- #### ⚠️ 注意事项(代价与限制): | 缺点 | 说明 | |------|------| | 📉 **写入性能下降** | 每次插入、更新、删除数据,MySQL 也要同步更新索引结构,因此会略微降低写操作的速度。 | | 💾 **占用磁盘空间** | 索引本身需要存储空间,尤其是大或长字符串字段。 | | 🔄 **不是所有情况都适合建索引** | 如果很小,或者 `name` 值重复率极高(如性别字段),索引可能不会被使用或效果差。 | --- ### ✅ 最佳实践建议 - 对于 `employee.name` 这种用于搜索、更新、删除的关键字段,**强烈建议添加索引**。 - 若 `name` 具有唯一性(每个员工姓名唯一),可考虑使用**唯一索引**防止重复: ```sql CREATE UNIQUE INDEX idx_employee_name ON employee(name); ``` - 生产环境中应结合执行计划分析索引使用情况: ```sql EXPLAIN SELECT * FROM employee WHERE name = 'John Doe'; ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值