oracle非空约束,修改联合主键

本文介绍如何使用SQL命令来修改数据库表结构,包括修改字段为非空、删除主键及重新定义主键等操作。

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

         alter table KTOUT_MENZENPERSON modify icd10 not null;
         alter table KTOUT_MENZENPERSON drop primary key;
alter table KTOUT_MENZENPERSON modify (primary key(REG_ID, ORG_CODE, ORG_REG_ID, SMONTHDAY,icd10));

<think>我们被要求回答“如何在数据库中为多个字段建立联合主键”,并参考了站内引用。根据引用[2]中提到的主键定义:“主键是候选键中的一个,主要用于更方便的检索和管理数据”,以及引用[5]中关于关系表设计的例子(学生和课程的多对多关系,通常需要联合主键)。 联合主键(Composite Primary Key)是指由两个或更多个字段组合起来作为表的主键。在关系型数据库中,联合主键用于唯一标识表中的每一行记录,且这些字段的组合必须是唯一的,并且不能全部为NULL。 下面以几种常见数据库系统为例,说明如何创建联合主键: 1. 在创建表时定义联合主键: - 通用SQL语法(适用于大多数关系型数据库如MySQL, PostgreSQL, SQL Server等): ```sql CREATE TABLE 表名 ( 字段1 数据类型, 字段2 数据类型, 其他字段 数据类型, PRIMARY KEY (字段1, 字段2) ); ``` - 示例(学生选课表,假设一个学生可以选择多门课程,但同一个学生同一门课程只能选一次): ```sql CREATE TABLE student_course ( student_id INT, course_id INT, grade DECIMAL(5,2), PRIMARY KEY (student_id, course_id) -- 将student_id和course_id定义为联合主键 ); ``` 2. 在已有表上添加联合主键(如果表已经存在): ```sql ALTER TABLE 表名 ADD PRIMARY KEY (字段1, 字段2); ``` 注意:在添加联合主键之前,必须确保这些字段的组合是唯一的,且没有NULL值。否则,操作会失败。 3. 特殊数据库系统的语法差异: - Oracle数据库:与上述通用语法相同。 - SQLite:同样支持上述语法。 4. 联合主键的注意事项: - **唯一性约束**:联合主键要求这些字段的组合值在表中是唯一的。例如,在`student_course`表中,同一个`student_id`和`course_id`的组合只能出现一次。 - **约束**:联合主键的每个字段都不能为NULL。 - **外键引用**:当其他表需要引用这个联合主键时,外键也必须由同样多个字段组成,并且类型匹配。例如,如果有一个表需要引用`student_course`的联合主键,则外键定义如下: ```sql CREATE TABLE another_table ( ... , student_id INT, course_id INT, FOREIGN KEY (student_id, course_id) REFERENCES student_course(student_id, course_id) ); ``` - **性能考虑**:联合主键的字段顺序可能会影响性能,因为索引(主键自动创建索引)是从左到右构建的。通常,将最常用作查询条件的字段放在前面,或者将区分度高的字段放在前面,可以提高查询效率[^4]。 5. 联合主键与自增主键的对比: - 引用[1]中建议:“不要使用任何有业务含义的字段作主键,而是使用一个自增的(或者系统生成的)没有实际业务意义的字段作为主键”。但在多对多关系表中,联合主键(由两个外键组成)是常见的做法,且这两个字段虽然具有业务含义(它们是其他表的主键),但在这个关系表中,它们共同构成一个没有额外业务意义的主键(仅表示关联)。因此,在这种情况下使用联合主键是合理的。 - 如果考虑到扩展性,有时也会在关系表中添加一个独立的无意义主键(如自增ID),而将两个外键字段设置为唯一约束。这样,在需要引用该关系表时,可以使用单字段主键。但这样会增加一个额外的字段和索引。具体选择取决于业务需求。 6. 示例:根据引用[5]中的学生选课关系,设计表结构: ```sql -- 学生表 CREATE TABLE student ( student_id INT PRIMARY KEY COMMENT '学号', name VARCHAR(50) COMMENT '姓名', age INT COMMENT '年龄', gender CHAR(1) COMMENT '性别' ) COMMENT='学生表'; -- 课程表 CREATE TABLE course ( course_id INT PRIMARY KEY COMMENT '课程号', course_name VARCHAR(100) COMMENT '课程名', credit INT COMMENT '学分' ) COMMENT='课程表'; -- 选课关系表(使用联合主键) CREATE TABLE enrollment ( student_id INT COMMENT '学号', course_id INT COMMENT '课程号', grade DECIMAL(5,2) COMMENT '成绩', PRIMARY KEY (student_id, course_id), FOREIGN KEY (student_id) REFERENCES student(student_id), FOREIGN KEY (course_id) REFERENCES course(course_id) ) COMMENT='选课关系表'; ``` 7. 修改已有表添加联合主键的示例: 假设已经存在一个表`enrollment`,但没有定义主键,我们可以这样添加联合主键: ```sql ALTER TABLE enrollment ADD PRIMARY KEY (student_id, course_id); ``` 8. 删除联合主键: 如果需要删除联合主键(注意:删除主键会同时删除自动创建的索引): ```sql ALTER TABLE enrollment DROP PRIMARY KEY; -- 在MySQL中 ``` 在其他数据库系统中,语法可能略有不同,例如在SQL Server中: ```sql ALTER TABLE enrollment DROP CONSTRAINT PK_enrollment; -- PK_enrollment是主键约束的名称 ``` 总结:联合主键的创建通过`PRIMARY KEY`关键字后面跟上多个字段来实现。在数据库设计中,联合主键常用于多对多关系表,以确保两个外键字段的组合唯一性。 根据引用[3]的建议,我们在设计表时应该为表和字段添加注释,并在SQL书写时保持格式规范。 §§相关问题§§ 1. 联合主键和唯一约束有什么区别? 2. 联合主键在哪些场景下比单字段主键更合适? 3. 如何为联合主键创建外键引用? 4. 联合主键对数据库查询性能有什么影响? 5. 在分布式数据库(如GoldenDB)中创建联合主键有什么特殊注意事项?</think>### 如何在数据库中创建联合主键 在数据库设计中,联合主键(Composite Primary Key)是由多个字段组合形成的主键,用于唯一标识表中的每一行记录。以下是具体实现方法和注意事项: #### 一、创建联合主键的基本语法 ```sql CREATE TABLE 表名 ( 字段1 数据类型, 字段2 数据类型, ..., PRIMARY KEY (字段1, 字段2) -- 联合主键定义 ); ``` **示例:学生选课表** ```sql CREATE TABLE student_course ( student_id INT NOT NULL COMMENT '学号', course_id INT NOT NULL COMMENT '课程号', grade DECIMAL(5,2) COMMENT '成绩', PRIMARY KEY (student_id, course_id) -- 联合主键 ) COMMENT='学生选课记录'; ``` > 此设计确保同一学生不能重复选修同一门课程[^5] #### 二、修改已有表添加联合主键 ```sql ALTER TABLE 表名 ADD PRIMARY KEY (字段1, 字段2); ``` **示例:** ```sql ALTER TABLE orders ADD PRIMARY KEY (order_id, customer_id); ``` #### 三、联合主键设计原则 1. **最小化原则** 使用最少的字段组合确保唯一性,如学生选课表只需`(student_id, course_id)` 2. **稳定性原则** 选择不常变更的字段(如学号而手机号)[^1] 3. **数据类型优化** 优先使用整数类型(INT/BIGINT)而字符串,提升索引效率[^2] 4. **避免业务耦合** 不推荐使用姓名+生日等业务字段组合,建议增加代理键(surrogate key)[^1] #### 四、联合主键 vs 单字段主键 | **特性** | 联合主键 | 单字段主键 | |----------------|-----------------------------|-----------------------| | 业务关联性 | 直接体现业务关系[^5] | 无业务含义 | | 存储效率 | 节省存储间 | 需额外存储代理键 | | 外键引用 | 需多字段引用 | 单字段引用简单 | | 索引效率 | 最左前缀查询高效[^4] | 全字段查询高效 | | 适用场景 | 关系表(如选课/订单明细) | 实体表(如学生/商品) | #### 五、性能优化建议 1. **字段顺序策略** 高频查询字段放联合主键左侧: ```sql PRIMARY KEY (department_id, employee_id) -- 部门查询更频繁 ``` 2. **避免过大字段** 禁止在联合主键中使用`TEXT/BLOB`类型 3. **索引覆盖原则** 当联合主键包含所有查询字段时,可避免回表操作[^4] 4. **分布式系统注意** 在GoldenDB等分布式数据库中,联合主键需均匀分布数据,避免热点问题 #### 六、联合主键的外键关联 ```sql CREATE TABLE order_details ( order_id INT, product_id INT, quantity INT, PRIMARY KEY (order_id, product_id), FOREIGN KEY (order_id) REFERENCES orders(order_id), FOREIGN KEY (product_id) REFERENCES products(product_id) ) COMMENT='订单明细表'; ``` #### 七、查看联合主键 ```sql SELECT COLUMN_NAME, ORDINAL_POSITION FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE TABLE_NAME = 'student_course' AND CONSTRAINT_NAME = 'PRIMARY'; ``` 输出示例: | COLUMN_NAME | ORDINAL_POSITION | |-------------|------------------| | student_id | 1 | | course_id | 2 | > 设计良好的联合主键可显著提升多表连接查询性能[^3]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值