数据库如何建立联合主键

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环境)。

直接进入企业管理器,选择数据库,找到表点设计表。然后按住CTRL选中要设为主键的值,然后右键选择设为主键(确认数据库中不存在跟主键冲突的数据)追问

这样设定的主键与要求不一样啊。我想让两个字段不同时重复(这种方法我试过了,不行)
另外,能给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背后使用了哈希算法和哈希表。 

以上是关于数据库如何建立联合主键的主要内容,如果未能解决你的问题,请参考以下文章

JPA注解实现联合主键

mysql中,索引,主键,唯一索引,联合索引的区别是?对数据库的性能有啥影响?

con sno联合主键怎么设置

如何创建联合主键

联合主键

db2中创建联合主键,发现一个字段可以为null,但是db2不让创建