MySQL - 组合主键



MySQL **组合主键**是由表中两个或多个列组成的键,用于唯一标识一条记录(同一表行中值的组合)。它也可以被描述为主键在多个列上创建。

在表的多个列上使用组合主键,这些列的组合保证了唯一性,即使这些列单独可能并不保证唯一性。因此,当数据库表没有任何列能够单独识别表中唯一行(或记录)时,我们可能需要两个或多个字段/列才能从表中获取唯一记录/行。

创建 MySQL 组合主键

要在 MySQL 表中创建组合主键,我们使用 CREATE TABLE 语句中的 PRIMARY KEY 关键字在表的两个或多个列上创建一个主键。组合主键必须具有以下特性:

  • 组合主键可以是外键的一部分,也可以不是。
  • 组合主键不能为 NULL。
  • 组合主键也可以通过组合多个候选键来创建。
  • 它也被称为复合键。
  • 复合键中的所有属性都是外键。

语法

以下是创建表时创建组合主键的语法:

CREATE TABLE table_name(
   column1 datatype, column2 datatype, column3 datatype..., 
   CONSTRAINT composite_key_name 
   PRIMARY KEY(column_name1, column_name2,..)
);

示例

在下面的示例中,我们尝试创建一个名为 CUSTOMERS 的表,并在 ID 和 NAME 列上添加组合主键,如下所示:

CREATE TABLE CUSTOMERS (
   ID INT NOT NULL,
   NAME VARCHAR (20) NOT NULL,
   AGE INT NOT NULL,
   ADDRESS CHAR (25),
   SALARY DECIMAL (18, 2),
   PRIMARY KEY(ID, NAME)
);

PRIMARY KEY 添加到 CUSTOMERS 表的 ID 和 NAME 列。插入到这些列中的值的组合必须是唯一的,即使各个列值有重复。

验证

要验证是否创建了组合主键,让我们使用 DESC 查询显示 CUSTOMERS 表的表定义:

字段 类型 Null 默认值 额外
ID int NO PRI NULL
NAME varchar(20) NO PRI NULL
AGE int NO NULL
ADDRESS char(25) YES NULL
SALARY decimal(18, 2) YES NULL

删除 MySQL 组合主键

我们可以使用 ALTER TABLE... DROP 语句删除 MySQL 组合主键。

语法

以下是删除表列中组合键的语法:

ALTER TABLE table_name DROP PRIMARY KEY;

示例

使用以下 SQL 语句,我们可以从表中删除**组合键**约束:

ALTER TABLE CUSTOMERS DROP PRIMARY KEY;

验证

要验证组合键是否已删除,我们使用 DESC 关键字显示 CUSTOMERS 表:

字段 类型 Null 默认值 额外
ID int NO NULL
NAME varchar(20) NO NULL
AGE int NO NULL
ADDRESS char(25) YES NULL
SALARY decimal(18, 2) YES NULL

使用客户端程序创建组合主键

我们也可以在字段上应用组合键约束以使用客户端程序唯一标识。

语法

要在 PHP 程序中对字段应用组合键,我们需要使用**mysqli**函数**query()**执行“创建/修改”语句,如下所示:

$sql = 'ALTER TABLE customers ADD PRIMARY KEY(cust_Id, cust_Name)';
$mysqli->query($sql);

要在 JavaScript 程序中对字段应用组合键,我们需要使用**mysql2**库的**query()**函数执行“创建/修改”语句,如下所示:

sql = `CREATE TABLE employee(ID Int NOT NULL, emp_Id INT NOT NULL, emp_Name varchar(25), PRIMARY KEY(ID, emp_Id))`;
con.query(sql);  

要在 Java 程序中对字段应用组合键,我们需要使用**JDBC**函数**execute()**执行“创建/修改”语句,如下所示:

String sql = "Alter TABLE customers ADD PRIMARY KEY(cust_Id, cust_Name)";
statement.execute(sql);

要在 python 程序中对字段应用组合键,我们需要使用**MySQL Connector/Python**的**execute()**函数执行“创建/修改”语句,如下所示:

composite_key_query = 'CREATE TABLE TEST(ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, MOBILE BIGINT, CONSTRAINT CK_TEST PRIMARY KEY (ID, MOBILE))'
cursorObj.execute(composite_key_query)

示例

以下是程序:

$dbhost = 'localhost';
$dbuser = 'root';
$dbpass = 'password';
$dbname = 'TUTORIALS';
$mysqli = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($mysqli->connect_errno) {
    printf("Connect failed: %s
", $mysqli->connect_error); exit(); } // printf('Connected successfully.
'); //creating composite key using alter statement. $sql = 'ALTER TABLE customers ADD PRIMARY KEY(cust_Id, cust_Name)'; if ($mysqli->query($sql)) { echo "composite key column created successfully in customers table \n"; } if ($mysqli->errno) { printf("Table could not be created!.
", $mysqli->error); } $mysqli->close();

输出

获得的输出如下:

composite key column created successfully in customers table
var mysql = require("mysql2");
var con = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "password",
}); //Connecting to MySQL

con.connect(function (err) {
  if (err) throw err;
  //   console.log("Connected successfully...!");
  //   console.log("--------------------------");
  sql = "USE TUTORIALS";
  con.query(sql);

  //creating a composite key column during the table creation...!
  sql = `CREATE TABLE employee(ID Int NOT NULL, emp_Id INT NOT NULL, emp_Name varchar(25), PRIMARY KEY(ID, emp_Id))`;
  con.query(sql);

  //describe table details
  sql = "DESCRIBE TABLE employee";
  con.query(sql, function (err, result) {
    if (err) throw err;
    console.log(result);
  });
});          

输出

生成的输出如下:

[
    {
      id: 1,
      select_type: 'SIMPLE',
      table: 'employee',
      partitions: null,
      type: 'ALL',
      possible_keys: null,
      key: null,
      key_len: null,
      ref: null,
      rows: 1,
      filtered: 100,
      Extra: null
    }
]   
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class CompositeKey {
   public static void main(String[] args) {
      String url = "jdbc:mysql://127.0.0.1:3306/TUTORIALS";
      String username = "root";
      String password = "password";
      try {
         Class.forName("com.mysql.cj.jdbc.Driver");
         Connection connection = DriverManager.getConnection(url, username, password);
         Statement statement = connection.createStatement();
         System.out.println("Connected successfully...!");

         //Create a composite key in the customers table...!;
         String sql = "Alter TABLE customers ADD PRIMARY KEY(cust_Id, cust_Name)";
         statement.execute(sql);
         System.out.println("Composite key created successfully...!");
         ResultSet resultSet = statement.executeQuery("DESCRIBE customers");
         while (resultSet.next()){
            System.out.println(resultSet.getString(1)+" "+resultSet.getString(2)+" "
                    +resultSet.getString(3)+ " "+ resultSet.getString(4));
         }
         connection.close();
      } catch (Exception e) {
         System.out.println(e);
      }
   }
}       

输出

获得的输出如下所示:

Connected successfully...!
Composite key created successfully...!
Cust_ID int NO PRI
Cust_Name varchar(30) NO PRI
import mysql.connector
#establishing the connection
connection = mysql.connector.connect(
    host='localhost',
    user='root',
    password='password',
    database='tut'
)
cursorObj = connection.cursor()
# Create table 
composite_key_query = '''CREATE TABLE TEST(ID INT NOT NULL, NAME VARCHAR (20) NOT NULL, AGE INT NOT NULL, MOBILE BIGINT, 
CONSTRAINT CK_TEST PRIMARY KEY (ID, MOBILE))'''
cursorObj.execute(composite_key_query)
connection.commit()
print("Composite key column is created successfully!")
cursorObj.close()
connection.close()           

输出

以下是上述代码的输出:

Composite key column is created successfully!
广告