数据库设计误区:备用字段 / 保留字段 / 预留字段

在数据库设计中,预留大量备用字段看似预防未来需求,实则带来空间浪费、管理混乱及扩展难题。本文剖析其弊病,提倡按需设计,灵活应对变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【现象描述】

在数据表中,不仅设计了当前所需要的字段,而且还在其中留出几个字段作为备用。
比方说,我设计了一个人员表(Person),其中已经添加了各种必要的字段,包括姓名(Name)、性别(Sex)、出生年月日(birthday)等等。大功告成之后,我忽然想到,将来系统中应该还会有很多其它与人相关的内容吧,比方说毕业院校,比方说工作单位等等,尽管现在根本不需要填写,以后可能还是会用到的吧。拍脑袋一项,那就加入5个varchar2型的字段,分别叫做Text1、Text2……Text5,然后又想,应该还有一些日期型的字段需要备用,就又建立了三个date型的字段,分别起名叫做date1、date2、date3,……

【原因分析】

大家应该已经看出问题了,在这个数据表中存在大量暂时无用的字段,我们可以称之为备用字段,它们的作用是什么呢?就是以防万一,防备可能的情况。
这似乎可以叫做防患于未然,等到需要的时候,就不需在表中增加新的字段了,而且这样做的话,一个表的数据应该会被存储在相邻的物理空间中,这对于性能也是有好处的。
另外的原因就是,在古老的数据库中,如果改变数据库的定义(包括增加字段、改变字段的类型、删除字段等等),那么其中所有的数据就会丢失,所以这项工作非常麻烦,我们需要先建立临时表,将数据备份出来,然后创建新表,将数据导入其中,最后再删除原来的表。

【问题所在】

这样的做法对于项目会导致很多问题,而且原先想要解决的问题并不一定能够解决,不信的话,请往下看。
问题一:增加大量备用字段,必定会浪费很多空间,尽管其中可能都没有具体的数据,但是仅仅是空字段也会占据一定的空间的。
问题二:由于命名的特点,如果没有完善的文档管理流程,用不了多久(可能也就是两三年),就没有人能够说清楚到底哪个字段代表的是什么意义了。就算有文档管理,这些管理工作也会比较麻烦,而且在每次使用的时候都需要申请,还有可能会出现冲突的情况。
问题三:增加了这些备用字段就真的会够用吗?不一定,因为我们只是每个类型的字段留出几个备用,如果数量超过,或者要使用特殊的、不常用的类型的时候,还是需要增加新的字段。比方说在上述的Person表中,我们要存储照片,那么可能就要增加一个blob类型的photo字段,这在初期设计的时候可不一定会留出这样的备用字段。而且如果没有完善的管理,谁又能说清楚倒底哪个字段已经被使用,哪个字段还可以使用呢?到时候还不是要增加新的字段。

【解决方案】

其实上面的这种设计方式就是一种“过度设计”,我们应该做的就是“按需设计”,在经过详细有效的分析之后,在数据表中只放置必要的字段,而不要留出大量的备用字段。
当需要增加相关的信息的时候,就要具体情况具体分析:

  1. 如果数量很少,而且信息的性质与原表密切相关,那么就可以直接在原表上增加字段,并将相关的数据更新进去;
  2. 如果数量较大,或者并非是原表对象至关重要的属性,那么就可以新增一个表,然后通过键值连接起来;
  3. 对于表的数据的存储位置所导致的性能问题,我们可以通过在特定时间对数据库的数据进行重组来解决,而这项工作对于长期运行的数据库来说,也是需要定期进行的。

作者:iw1210
来源:优快云
原文:https://blog.youkuaiyun.com/iw1210/article/details/44752771
版权声明:本文为博主原创文章,转载请附上博文链接!

<think>好的,我现在需要回答用户关于“getter/setter是什么”的问题。用户之前问过注解的作用,现在这个问题看起来是Java基础的一部分,可能用户在学习面向对象编程或者Java Bean的相关知识。 首先,我要确定用户的知识水平。他们可能刚开始学Java,所以需要简明扼要的解释,避免使用过多专业术语,但又要准确。我需要解释getter和setter的基本概念,为什么存在,以及它们的作用。 接下来,我应该考虑用户可能的疑惑点。比如,为什么需要这些方法,而不是直接访问字段?这时候要提到封装的概念,数据保护,以及如何通过方法来控制访问和修改数据。可能需要举一个例子,比如一个Person类,有name和age字段,直接访问可能导致不合理的数据,比如age为负数,而setter可以加入验证逻辑。 然后,可能需要提到Lombok库的注解,比如@Getter和@Setter,因为用户之前的问题涉及注解,可能他们知道或使用过Lombok,这样能连接前后的知识点,帮助用户理解关联。 另外,用户可能想知道getter/setter的命名规范,比如方法名以get或set开头,后面跟大写字母开头的字段名,这是Java Bean的标准,确保框架和工具能正确识别这些方法。 还要考虑应用场景,比如在Java Bean中,很多框架(如Spring)依赖getter和setter来进行依赖注入、数据绑定等操作。没有这些方法,某些框架可能无法正常工作。 可能的误区是用户认为写getter/setter很繁琐,这时候可以提到IDE的自动生成功能,或者Lombok这样的工具来简化代码。 需要结构清晰,分点解释,可能用示例代码展示直接访问字段的问题和使用getter/setter后的改进。同时,对比有无这些方法的情况,突出其重要性。 最后,总结getter/setter的作用,强调封装的重要性,以及它们如何提升代码的可维护性和安全性。</think>Getter(获取器)和 Setter(设置器)是面向对象编程中用于**控制类属性访问**的特殊方法,通过这两个方法实现对类成员变量的**安全读写操作**。 --- ### **核心作用** | 作用类型 | 具体表现 | |-------------------|--------------------------------------------------------------------------| | **数据封装** | 隐藏类属性的存储细节(如`private String name`) | | **访问控制** | 通过方法暴露读写权限(如只提供getter实现只读属性) | | **数据校验** | 在setter中加入逻辑验证(如年龄不能为负数) | | **行为扩展** | 在读写时触发额外操作(如数据变更日志记录) | | **兼容性维护** | 修改内部存储结构时不影响外部调用(如`getAge()`可改为计算值而不改接口) | --- ### **标准写法示例** ```java public class Person { private String name; private int age; // Getter public String getName() { return name; } // Setter(带基础校验) public void setName(String name) { if(name != null && !name.isEmpty()) { this.name = name; } } // Getter public int getAge() { return age; } // Setter(带业务逻辑) public void setAge(int age) { if(age >= 0 && age <= 150) { // 防止不合理年龄 this.age = age; } else { throw new IllegalArgumentException("无效年龄值"); } } } ``` --- ### **直接访问字段 vs 使用Getter/Setter** **危险写法(不推荐)** ```java person.age = -25; // 直接赋非法值 System.out.println(person.age); ``` **安全写法(推荐)** ```java person.setAge(-25); // 会触发异常 System.out.println(person.getAge()); ``` --- ### **现代开发中的演进** 1. **Lombok简化**(通过注解自动生成) ```java @Getter @Setter private String email; ``` 2. **记录类**(Java 16+) ```java public record User(String name, int age) {} // 自动生成final字段和getter ``` 3. **框架集成** - Spring依赖getter/setter进行依赖注入 - Jackson通过getter/setter序列化JSON --- ### **为什么需要遵守JavaBean规范** 1. **框架兼容性**:大多数Java框架(如Spring, Hibernate)通过getter/setter操作对象 2. **可维护性**:统一的方法命名规范(`getXxx()`/`setXxx()`)提高代码可读性 3. **动态访问**:支持反射机制动态获取/修改属性值 --- **总结**:Getter/Setter是面向对象**封装特性**的具体实现,既能保护数据完整性,又能为后续功能扩展预留空间,是Java开发中最基础却至关重要的设计模式。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值