由一个问题引发的思考——关于数据库的外键约束

   出于系统设计的需要,数据库中的表添加了外键约束,由于自己的知识不足,这就导致了在删除数据时被外键约束了,不能删除。So,赶紧学习,赶紧补充知识。问度娘问谷歌,首先得知道什么是“外键约束”,网上自有高人在——“如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表。外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常的维护工作更加轻松。”(参考

通过看教程知道了PowerDesigner这个强大的工具,用它可以生成级联约束,通过触发器来约束修改数据库,就是在子表插入数据时,检查父表是否存在相应的外键,如果不存在则禁止添加,当删除父表数据时,字表中相关的数据自动被删除。这功能真是强大,可问题又来了,从来没用过PowerDesigner,只能现学现卖了,问题是你懂的,这个软件是英文版的,汉化的又不够好,英语的重要性又一次体现了出来。可是数据库已经建好了,怎么才能导入的PD中呢,还好强大的PD可以进行“逆向工程”,就是把数据库导入到PD中进行编辑,再更新到数据库,过程总是不顺利的,首先是数据库版本不兼容,我安装的PD是15.1,好像是不支持Sql Server 2008,导入数据时总报错,苦逼的我也不知道是什么问题,就一个劲儿的问度娘,网上说的好多解决方法都不适用,好在我的耐性还是比较强的,终于找到了良药—— PowerDesigner 逆向工程 unable to list the tables ,用Sql语句将数据库的兼用级别改为90:

 EXEC sp_dbcmptlevel "dbName", "90";
                 GO

数据库终于导入成功了,内心这个小激动。接下来就是编辑数据库关系了:

编辑完关系该更新数据库了,不知为什么更新的时候不能生成字表插入的触发器,只能手动添加。谁知道这只是小试牛刀,悲剧的还在后头,原来的数据库是有数据,更新完之后数据都没了,幸亏我有备份,不哭。那就把数据导入进来吧,总有解决不完的问题——附加数据库的时候因为数据库名是一样的,所以要先修改数据库名,妹的,又报错:

还好有大牛——MS SQL修改数据库名称

由于是昨天晚上太晚了,没弄完,所以今天有些细节记不太清了,以后会详细记录的。


主要感悟有两点:

一是不要怕遇到问题,有了问题我们才能在解决问题的过程中学到知识,成长的路上会有各种各样的问题,技术总是在解决问题中练就的。

二要坚持不放弃,学习就是需要一种锲而不舍的精神,多试几次,不要轻言放弃。有时,我会为了解决一个问题思考好几天,最终总会找到答案。


### MySQL 约束的使用方法与示例 #### 什么是约束约束是关系型数据库中用于维护数据完整性和一致性的一种机制。在约束的作用下,子表中的某个字段必须对应于父表中存在的值,或者为 `NULL` 值。这可以有效防止孤立的数据存在于子表中[^3]。 #### 约束的重要性 通过约束,可以在多个表之间建立关联关系,确保数据的一致性并优化数据库的关系结构。这种特性对部系统的依赖较少,能够在数据库层面上强制执行业务规则[^2]。 --- #### 创建带有约束的表 ##### 示例语法 以下是创建约束的表的标准 SQL 语句: ```sql CREATE TABLE parent_table ( id INT PRIMARY KEY, name VARCHAR(50) ); CREATE TABLE child_table ( id INT PRIMARY KEY, parent_id INT, description TEXT, CONSTRAINT fk_parent FOREIGN KEY (parent_id) REFERENCES parent_table(id) ); ``` 在此示例中: - `child_table.parent_id` 是字段。 - 它引用了 `parent_table.id` 字段。 - 如果尝试向 `child_table` 插入一条记录,而该记录的 `parent_id` 不在 `parent_table` 中,则操作会被拒绝[^4]。 --- #### 修改现有表以添加约束 如果已经存在两个独立的表,可以通过 `ALTER TABLE` 添加约束: ```sql -- 假设已有两张表:tb_dept 和 tb_employee ALTER TABLE tb_employee ADD CONSTRAINT fk_department FOREIGN KEY (deptId) REFERENCES tb_dept(id); ``` 此命令将在 `tb_employee.deptId` 上添加一个约束,使其指向 `tb_dept.id`[^4]。 --- #### 删除约束 当不再需要某条约束时,可以将其移除而不影响其他数据结构: ```sql ALTER TABLE child_table DROP FOREIGN KEY fk_parent; ``` 注意:删除不会自动清理相关联的数据,因此需谨慎处理[^4]。 --- #### 数据插入与更新行为 1. **插入数据** 当插入新记录到子表时,必须保证其字段对应的值已在父表中存在;否则会抛出错误提示[^3]。 2. **级联操作** 可以为定义额的行为选项(如 ON DELETE 或 ON UPDATE),以便更灵活地管理跨表间的影响。例如: ```sql CREATE TABLE orders ( order_id INT PRIMARY KEY, customer_id INT, total DECIMAL(10, 2), CONSTRAINT fk_customer_orders FOREIGN KEY (customer_id) REFERENCES customers(customer_id) ON DELETE CASCADE -- 自动删除订单 ON UPDATE NO ACTION -- 更新时不采取任何动作 ); ``` 此处设置了两种情况下的默认响应方式——删除客户资料时连同他们的所有订单一起清除 (`CASCADE`) ,而在更改顾客编号时保持原样(`NO ACTION`)[^4]。 --- #### 性能考量 尽管有助于保障数据质量,但在高负载环境下可能带来性能瓶颈。特别是对于频繁写入的大规模事务来说,启用验证增加了额的时间开销。此时建议关闭内置功能转由应用程序自行控制校验流程[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值