数据库如何建立联合主键
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库如何建立联合主键相关的知识,希望对你有一定的参考价值。
比如:
--1)
create table T_Student(
Fson char(10) primary key,--学号
Fsname nvarchar(10) not null,--姓名
Fssex nchar(1) check(Fssex in('男','女')),--性别
Fsage int check(Fsage between 15 and 45),--年龄
Fsdept nvarchar(20) default '计算机系'--所在系
)
create table T_Course(
Fcno char(10) primary key,--课程号
Fcname nvarchar(20) not null,--课程名
Fccredit int check(Fccredit>0),--学分
Fsemster int check(Fsemster>0),--学期
Fperiod int check(Fperiod>0)--学时
)
create table T_Sc(
Fsno char(10) foreign key(Fsno) references T_student(Fson),--学号
Fcno char(10) foreign key(Fcno) references T_Course(Fcno),--课程号
Fgrade int check(Fgrade between 0 and 100),--成绩
primary key(Fsno,Fcno)--这一句有误
)
我想让T_Sc这个表的Fsno和Fcno作为主键,两个值不能同时重复
比如:
9512101 C01
9512101 C02
这是合法的
9512101 C01
9512101 C02
这是非法的
这应当如何创建(用sql语句sql server环境)。
这样设定的主键与要求不一样啊。我想让两个字段不同时重复(这种方法我试过了,不行)
另外,能给sql语句版的么?
ALTER TABLE T_Sc ADD PRIMARY KEY (Fsno,Fcno);
参考技术A 不行,是因为表中对应列已经存在重复值。先导出数据,创建好后再导入数据。联合主键
一:背景介绍
在很多项目中,一个数据库表不仅仅只有一个约束条件,所以需要设置多个主键,来构成约束。但是在同时对多个主键进行增删改查的操作后,就难以下手了,所以需要引入联合主键的概念,将多个主键糅合归纳到一个主键中,从而方便相关操作的实行。
二:具体操作
不多说,直接先看数据库的结构:
表的字段值:
其主键为:
在hibernate下,我们主要来看一下实体bean的配置,其他的具体CRUD操作此处不做编写:
实体TpsControl类代码如下: package yspos.boss.urm.entity; import java.io.Serializable; import javax.persistence.AttributeOverride; import javax.persistence.AttributeOverrides; import javax.persistence.Column; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; /** * Cmmtinorg entity. */ @Entity -----------注解 @Table(name = "TPS_CONTROL") ------------------对应的表名称 public class TpsControl implements Serializable { --1.必须实现Serializable private static final long serialVersionUID = -202989070727685638L; private TpsControlId id; ----------联合主键,可以映射到实体类TpsControlId private String ifControl; private Integer concurrentNumber; private Integer monthVisit; private String reqIp; private String remark; private Integer accNameLimit; public TpsControl() { ------必须有默认的 public无参数的构造方法 } public TpsControl(TpsControlId id) { this.id = id; } public TpsControl(TpsControlId id,String ifControl, Integer concurrentNumber, Integer monthVisit, String reqIp, String remark, Integer accNameLimit) { this.id = id; this.ifControl = ifControl; this.concurrentNumber = concurrentNumber; this.monthVisit = monthVisit; this.reqIp = reqIp; this.remark = remark; this.accNameLimit = accNameLimit; } @EmbeddedId ---将嵌入式主键类使用 @Embeddable 标注,表示这个是一个嵌入式类 @AttributeOverrides( { ----------------@AttributeOverrides 属性映射 @AttributeOverride(name = "src", column = @Column(name = "SRC", nullable = false, length = 5)), @AttributeOverride(name = "msgCode", column = @Column(name = "MSG_CODE", nullable = false, length = 20)), @AttributeOverride(name = "method", column = @Column(name = "METHOD", nullable = false, length = 30)) }) public TpsControlId getId() { return id; } public void setId(TpsControlId id) { this.id = id; } @Column(name = "IF_CONTROL", length = 1) -------对应于表字段的信息 public String getIfControl() { return ifControl; } public void setIfControl(String ifControl) { this.ifControl = ifControl; } @Column(name = "CONCURRENT_NUMBER", length = 10) public Integer getConcurrentNumber() { return concurrentNumber; } public void setConcurrentNumber(Integer concurrentNumber) { this.concurrentNumber = concurrentNumber; } @Column(name = "MONTH_VISIT", length = 20) public Integer getMonthVisit() { return monthVisit; } public void setMonthVisit(Integer monthVisit) { this.monthVisit = monthVisit; } @Column(name = "REQ_IP", length = 100) public String getReqIp() { return reqIp; } public void setReqIp(String reqIp) { this.reqIp = reqIp; } @Column(name = "REMARK", length = 100) public String getremark() { return remark; } public void setremark(String remark) { this.remark = remark; } @Column(name = "ACC_NAME_LIMIT", length = 10) public Integer getAccNameLimit() { return accNameLimit; } public void setAccNameLimit(Integer accNameLimit) { this.accNameLimit = accNameLimit; } }
联合主键类:
实体TpsControlId类如下: package yspos.boss.urm.entity; import javax.persistence.Column; import yspos.boss.cmmt.entity.CmmtcityId; public class TpsControlId implements java.io.Serializable { private static final long serialVersionUID = 2719054247718051949L; private String src; private String msgCode; private String method; public TpsControlId() { } public TpsControlId(String src, String msgCode, String method) { super(); this.src = src; this.msgCode = msgCode; this.method = method; } @Column(name = "SRC", nullable = false, length = 5) public String getSrc() { return src; } public void setSrc(String src) { this.src = src; } @Column(name = "MSG_CODE", nullable = false, length = 20) public String getMsgCode() { return msgCode; } public void setMsgCode(String msgCode) { this.msgCode = msgCode; } @Column(name = "METHOD", nullable = false, length = 30) public String getMethod() { return method; } public void setMethod(String method) { this.method = method; } public boolean equals(Object other) { ---必须覆盖 equals和 hashCode 方法 if ((this == other)) return true; if ((other == null)) return false; if (!(other instanceof TpsControlId)) return false; TpsControlId castOther = (TpsControlId) other; return ((this.getSrc() == castOther.getSrc()) || (this .getSrc() != null && castOther.getSrc() != null && this.getSrc().equals( castOther.getSrc()))) && ((this.getMsgCode() == castOther.getMsgCode()) || (this .getMsgCode() != null && castOther.getMsgCode() != null && this.getMsgCode() .equals(castOther.getMsgCode()))) && ((this.getMethod() == castOther.getMethod()) || (this .getMethod() != null && castOther.getMethod() != null && this.getMethod() .equals(castOther.getMethod()))); } public int hashCode() { int result = 17; result = 37 * result + (getSrc() == null ? 0 : this.getSrc().hashCode()); result = 37 * result + (getMsgCode() == null ? 0 : this.getMsgCode().hashCode()); result = 37 * result + (getMethod() == null ? 0 : this.getMethod().hashCode()); return result; } }
符合条件:
* 1.必须实现Serializable
* 2.必须有默认的 public无参数的构造方法、必须覆盖 equals和 hashCode 方法,这些要求与使用复合主键的要求相同
* 3.将嵌入式主键类使用 @Embeddable 标注,表示这个是一个嵌入式类。
--->如果要求一个类要去实现Serializable,往往表示这个类的实例要进行网络传输,从A系统传到B系统,以字节形式传输,到达B后再把这些字节恢复成对象;
--->equals和hashCode两个方法常用哈希算法相关,比如要把对象放入TreeSet容器里,就需要容器里元素对应的类要重写equals和hashCode方法,因为TreeSet背后使用了哈希算法和哈希表。
以上是关于数据库如何建立联合主键的主要内容,如果未能解决你的问题,请参考以下文章