关系型数据库中的主键和外键

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
简介: 关系型数据库中的主键和外键

关系型数据库中的主键和外键


在关系型数据库中,主键和外键是两个非常重要的概念。主键用于唯一地标识一条记录,而外键则用于建立表与表之间的关联关系。本文将会详细介绍主键和外键的概念、作用以及应用场景,并提供代码示例来说明它们在实际中的应用。


image.png


主键


在关系型数据库中,每个表都必须有一个主键。主键是一种用来唯一地标识一条记录的字段或字段组合。主键的值不能重复,也不能为 NULL。主键可以是表中任意一个字段,但通常会选择一个具有唯一性的字段作为主键。例如,在一个用户表中,可以选择用户的 ID 字段作为主键。


主键的作用是确保表中的每条记录都可以被唯一地标识。这在数据查询、修改和删除等操作中非常有用。如果没有主键,就无法准确地确定一条记录,这样就会影响数据库的数据完整性和一致性。


下面是一个示例表格,其中包含了主键的定义:


| User ID | Username | Email          | Phone          |
| ------- | -------- | --------------| -------------- |
| 1       | Alice    | alice@abc.com  | 123-456-7890   |
| 2       | Bob      | bob@abc.com    | 234-567-8901   |
| 3       | Carol    | carol@abc.com  | 345-678-9012   |

在这个示例中,User ID 是主键。


外键


在关系型数据库中,外键用于建立表与表之间的关联关系。外键是一个字段或字段组合,它与另一个表的主键相对应。外键用于确保表之间的数据完整性和一致性。当一个表的字段被作为外键引用到另一个表的主键时,这两个表之间就建立了关联关系。


外键的作用可以通过一个示例来说明。假设有两个表,一个是用户表,一个是订单表。用户表中有一个名为 User ID 的字段作为主键,订单表中有一个名为 User ID 的字段作为外键,用于与用户表建立关联关系。这样,每个订单都可以与一个用户对应,而且每个订单的 User ID 必须在用户表中存在,否则就无法插入该订单。


下面是一个示例表格,其中包含了外键的定义:


| Order ID | User ID | Order Date |
| --------| ------- | ---------- |
| 1       | 2       | 2022-01-01 |
| 2       | 1       | 2022-01-02 |
| 3       | 3       | 2022-01-03 |

在这个示例中,User ID 是外键。


应用场景


主键和外键在关系型数据库设计中都非常重要,它们可以确保数据的完整性和一致性。下面是一些主键和外键的应用场景:


主键


  1. 用户表中的 User ID 字段可以作为主键,确保每个用户是唯一的。
  2. 商品表中的 SKU 字段可以作为主键,确保每个商品是唯一的。
  3. 订单表中的 Order ID 字段可以作为主键,确保每个订单是唯一的。


外键


  1. 订单表中的 User ID 字段可以作为外键,与用户表建立关联关系,确保每个订单都对应一个用户。
  2. 订单详情表中的 Order ID 字段可以作为外键,与订单表建立关联关系,确保每个订单详情都对应一个订单。
  3. 购物车表中的 SKU 字段可以作为外键,与商品表建立关联关系,确保购物车中的商品都是有效的。


代码示例


下面是一个基于 Python 和 SQLite 的代码示例,用于说明主键和外键在实际中的应用。


首先,我们需要创建一个用户表和一个订单表:


import sqlite3
conn = sqlite3.connect('example.db')
# 创建用户表
conn.execute('''CREATE TABLE users
             (id INTEGER PRIMARY KEY,
              username TEXT NOT NULL,
              email TEXT NOT NULL,
              phone TEXT NOT NULL)''')
# 创建订单表
conn.execute('''CREATE TABLE orders
             (id INTEGER PRIMARY KEY,
              user_id INTEGER NOT NULL,
              order_date TEXT NOT NULL,
              FOREIGN KEY (user_id) REFERENCES users(id))''')

在这个示例中,我们使用 SQLite 数据库,并创建了一个 users 表和一个 orders 表。users 表中的 id 字段被定义为主键,orders 表中的 user_id 字段被定义为外键,与 users 表中的 id 字段建立了关联关系。


接下来,我们可以向用户表中插入一些数据:


# 插入用户数据
conn.execute("INSERT INTO users (username, email, phone) VALUES (?, ?, ?)",
             ('Alice', 'alice@example.com', '123-456-7890'))
conn.execute("INSERT INTO users (username, email, phone) VALUES (?, ?, ?)",
             ('Bob', 'bob@example.com', '234-567-8901'))
conn.execute("INSERT INTO users (username, email, phone) VALUES (?, ?, ?)",
             ('Carol', 'carol@example.com', '345-678-9012'))

然后,我们可以向订单表中插入一些数据:


# 插入订单数据
conn.execute("INSERT INTO orders (user_id, order_date) VALUES (?, ?)",
             (2, '2022-01-01'))
conn.execute("INSERT INTO orders (user_id, order_date) VALUES (?, ?)",
             (1, '2022-01-02'))
conn.execute("INSERT INTO orders (user_id, order_date) VALUES (?, ?)",
             (3, '2022-01-03'))

在这个示例中,我们向订单表中插入了一些数据,其中 user_id 字段指向了用户表中的对应数据。由于 user_id 字段被定义为外键,并且与 users 表中的 id 字段建立了关联关系,因此当插入数据时,如果 user_id 字段的值不在 users 表中存在,就会抛出错误。


总结


在关系型数据库中,主键和外键是非常重要的概念。主键用于唯一地标识一条记录,而外键用于建立表与表之间的关联关系。主键和外键可以确保数据的完整性和一致性,在数据库设计和开发中应用广泛。本文通过示例代码的方式,介绍了主键和外键在实际中的应用场景,希望对读者有所帮助。


相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
6月前
|
SQL 存储 Web App开发
PolarDB-X 分布式数据库中的外键
外键是关系型数据库中非常便利的一种功能,它通过一个或多个列为两张表建立连接,从而允许跨表交叉引用相关数据。外键通过约束来保持数据的一致性,通过级联来同步数据在多表间的更新和删除。在关系数据库系统中,大多数表都遵循外键的概念。
|
9月前
|
SQL 存储 Oracle
Oracle数据库中日期的操作、主键自增与分页查询
Oracle数据库中日期的操作、主键自增与分页查询
80 0
|
5月前
|
Oracle 关系型数据库 数据库
在Flink CDC中,使用Oracle 11g数据库的NUMBER类型作为主键
在Flink CDC中,使用Oracle 11g数据库的NUMBER类型作为主键
48 1
|
8月前
|
算法 NoSQL 关系型数据库
数据库主键一定要自增吗?有哪些场景不建议自增?
数据库主键一定要自增吗?有哪些场景不建议自增?
284 0
|
8月前
|
数据库 OceanBase
在OceanBase数据库中,当使用主键自增功能插入一条带有主键的数据
在OceanBase数据库中,当使用主键自增功能插入一条带有主键的数据
1137 1
|
10月前
|
SQL Java 关系型数据库
数据库表主键类型设计踩坑记录
数据库表主键类型设计踩坑记录
60 0
|
10月前
|
算法 安全 Java
数据库如何合理生成主键:UUID、雪花算法
1.使用自增主键的弊端 首先在实际工程中我们很少用1,2,3......这样的自增主键,原因如下: 主键冲突 性能问题 安全问题 主键冲突: 比如我要跨数据库进行数据同步、或者在分布式系统中跨“分区”进行数据同步,不难想象,1,2,3......这种递增的单数字是极容易产生冲突的。
258 0
|
10月前
|
Java 数据库 Spring
数据库|Spring·JPA设置复合主键
数据库|Spring·JPA设置复合主键
365 0
|
10月前
|
SQL 关系型数据库 MySQL
删除数据库中的所有外键(MySql)?
我不想手动删除所有的目录,有办法删除数据库中的所有外键约束吗? 可以使用此SQL生成ALTERTABLE: SELECT concat(‘alter table ‘,table_schema,’.’,table_name,’ DROP FOREIGN KEY ‘,constraint_name,’;’) FROM information_schema.table_constraints WHERE constraint_type=’FOREIGN KEY’ AND table_schema=’!!YOUR_SCHEMA_HERE!!’; 它将输出这样的SQL:
55 0
|
10月前
|
算法 关系型数据库 MySQL
数据库主键
数据库主键
102 0