Skip to content

Commit da35edf

Browse files
authored
Merge pull request #560 from bytebase/o-branch-8
docs: tweak add constraints
2 parents 294e51d + 23b9ef1 commit da35edf

File tree

6 files changed

+561
-495
lines changed

6 files changed

+561
-495
lines changed

content/reference/mysql/how-to/_layout.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,4 @@
1111

1212
## [How to ALTER TABLE](/reference/mysql/how-to/how-to-alter-table-mysql)
1313

14-
## [How to DROP CONSTRAINT](/reference/mysql/how-to/how-to-drop-constraint-mysql)
14+
## [How to ADD CONSTRAINT](/reference/mysql/how-to/how-to-add-constraint-mysql)
Lines changed: 265 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,265 @@
1+
---
2+
title: How to add a CONSTRAINT in MySQL
3+
updated_at: 2025/03/13 12:00:00
4+
---
5+
6+
_Official documentation: [ALTER TABLE](https://dev.mysql.com/doc/refman/8.0/en/alter-table.html)_
7+
8+
## Performance Considerations
9+
10+
<HintBlock type="info">
11+
12+
Adding constraints may affect query performance and application behavior. Ensure you understand the implications before proceeding.
13+
14+
Some organizations have strict approval processes. You can enforce [approval process](/docs/administration/custom-approval/) or [automated review](/docs/sql-review/review-rules/#column) via Bytebase.
15+
16+
</HintBlock>
17+
18+
1. **Schema Validation**: Adding constraints will validate all existing data, which can cause the operation to fail if any violations exist.
19+
20+
2. **Lock Duration**: Some constraint addition operations may lock tables during execution.
21+
22+
3. **Index Creation**: Many constraints (PRIMARY KEY, UNIQUE) automatically create indexes, which can be resource-intensive on large tables.
23+
24+
4. **Proper Planning**: Schedule constraint modifications during off-peak hours.
25+
26+
## Types of Constraints in MySQL
27+
28+
MySQL supports the following constraint types:
29+
30+
1. Primary Key constraints
31+
2. Foreign Key constraints
32+
3. Unique constraints
33+
4. Check constraints (supported from MySQL 8.0.16)
34+
5. Not Null constraints
35+
6. Default value constraints
36+
37+
## Adding Primary Key Constraints
38+
39+
```sql
40+
-- Add primary key constraint
41+
ALTER TABLE table_name
42+
ADD PRIMARY KEY (column_name);
43+
44+
-- Example
45+
ALTER TABLE customers
46+
ADD PRIMARY KEY (customer_id);
47+
48+
-- Composite primary key
49+
ALTER TABLE order_details
50+
ADD PRIMARY KEY (order_id, product_id);
51+
```
52+
53+
If you need to modify a column before adding it as a primary key:
54+
55+
```sql
56+
-- Make column NOT NULL and then add as primary key
57+
ALTER TABLE products
58+
MODIFY product_id INT NOT NULL AUTO_INCREMENT;
59+
60+
-- Then add the primary key
61+
ALTER TABLE products
62+
ADD PRIMARY KEY (product_id);
63+
```
64+
65+
## Adding Foreign Key Constraints
66+
67+
```sql
68+
-- Add foreign key constraint
69+
ALTER TABLE table_name
70+
ADD CONSTRAINT constraint_name FOREIGN KEY (column_name)
71+
REFERENCES referenced_table (referenced_column);
72+
73+
-- Example
74+
ALTER TABLE orders
75+
ADD CONSTRAINT fk_customer_id FOREIGN KEY (customer_id)
76+
REFERENCES customers (customer_id);
77+
78+
-- With ON DELETE and ON UPDATE options
79+
ALTER TABLE order_items
80+
ADD CONSTRAINT fk_order_id FOREIGN KEY (order_id)
81+
REFERENCES orders (order_id)
82+
ON DELETE CASCADE
83+
ON UPDATE RESTRICT;
84+
```
85+
86+
## Adding Unique Constraints
87+
88+
In MySQL, unique constraints are implemented as unique indexes:
89+
90+
```sql
91+
-- Add unique constraint
92+
ALTER TABLE table_name
93+
ADD CONSTRAINT constraint_name UNIQUE (column_name);
94+
95+
-- Example
96+
ALTER TABLE users
97+
ADD CONSTRAINT uk_email UNIQUE (email);
98+
99+
-- Composite unique constraint
100+
ALTER TABLE products
101+
ADD CONSTRAINT uk_sku_vendor UNIQUE (sku, vendor_id);
102+
```
103+
104+
## Adding Check Constraints
105+
106+
Available from MySQL 8.0.16 onwards:
107+
108+
```sql
109+
-- Add check constraint
110+
ALTER TABLE table_name
111+
ADD CONSTRAINT constraint_name CHECK (expression);
112+
113+
-- Example
114+
ALTER TABLE employees
115+
ADD CONSTRAINT chk_salary_positive CHECK (salary > 0);
116+
117+
-- Multiple check constraints
118+
ALTER TABLE products
119+
ADD CONSTRAINT chk_price_positive CHECK (price > 0),
120+
ADD CONSTRAINT chk_inventory_nonnegative CHECK (inventory >= 0);
121+
```
122+
123+
## Adding NOT NULL Constraints
124+
125+
```sql
126+
-- Add NOT NULL constraint by modifying the column
127+
ALTER TABLE table_name
128+
MODIFY column_name data_type NOT NULL;
129+
130+
-- Example
131+
ALTER TABLE orders
132+
MODIFY customer_id INT NOT NULL;
133+
```
134+
135+
## Adding Default Constraints
136+
137+
```sql
138+
-- Add default constraint
139+
ALTER TABLE table_name
140+
ALTER COLUMN column_name SET DEFAULT value;
141+
142+
-- Example
143+
ALTER TABLE orders
144+
ALTER COLUMN status SET DEFAULT 'pending';
145+
146+
-- Multiple default constraints
147+
ALTER TABLE users
148+
ALTER COLUMN active SET DEFAULT TRUE,
149+
ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP;
150+
```
151+
152+
## Common Errors and Solutions
153+
154+
See [MySQL Error Reference](/reference/mysql/error/overview/) for a comprehensive list of errors you may encounter. Below are common errors specific to adding CONSTRAINT operations and their solutions:
155+
156+
### Error 1452: Cannot add or update a child row: a foreign key constraint fails
157+
158+
```sql
159+
-- Check for violating rows
160+
SELECT * FROM child_table
161+
WHERE child_column NOT IN (
162+
SELECT parent_column FROM parent_table
163+
);
164+
165+
-- Fix the violating rows before adding constraint
166+
UPDATE child_table
167+
SET child_column = NULL
168+
WHERE child_column NOT IN (
169+
SELECT parent_column FROM parent_table
170+
);
171+
172+
-- Or insert missing parent rows
173+
INSERT INTO parent_table (parent_column)
174+
SELECT DISTINCT child_column
175+
FROM child_table
176+
WHERE child_column NOT IN (
177+
SELECT parent_column FROM parent_table
178+
);
179+
```
180+
181+
### Error 1062: Duplicate entry for key
182+
183+
This occurs when adding a unique constraint and duplicate values exist:
184+
185+
```sql
186+
-- Find duplicate values
187+
SELECT column_name, COUNT(*)
188+
FROM table_name
189+
GROUP BY column_name
190+
HAVING COUNT(*) > 1;
191+
192+
-- Fix duplicate values before adding constraint
193+
UPDATE table_name
194+
SET column_name = CONCAT(column_name, '_', id)
195+
WHERE column_name IN (
196+
SELECT column_name FROM (
197+
SELECT column_name, COUNT(*)
198+
FROM table_name
199+
GROUP BY column_name
200+
HAVING COUNT(*) > 1
201+
) t
202+
);
203+
```
204+
205+
### Error 3819: Check constraint is violated
206+
207+
When adding a check constraint, existing data might violate it:
208+
209+
```sql
210+
-- Find violating rows
211+
SELECT * FROM employees
212+
WHERE salary <= 0;
213+
214+
-- Update data to satisfy constraint before adding it
215+
UPDATE employees
216+
SET salary = 1000 WHERE salary <= 0;
217+
218+
-- Then add the check constraint
219+
ALTER TABLE employees
220+
ADD CONSTRAINT chk_salary_positive CHECK (salary > 0);
221+
```
222+
223+
### Error 1064: Syntax error when adding constraints
224+
225+
```sql
226+
-- Make sure you're using the correct syntax for your MySQL version
227+
-- Especially for CHECK constraints which were only added in 8.0.16
228+
229+
-- Check your MySQL version
230+
SELECT VERSION();
231+
```
232+
233+
## Best Practices
234+
235+
1. **Database Backup**: Always back up your database before adding constraints.
236+
237+
2. **Test Environment**: Test constraint additions in a development environment first.
238+
239+
3. **Data Validation**: Validate data before adding constraints to prevent failures.
240+
241+
```sql
242+
-- Example: Validate before adding NOT NULL constraint
243+
SELECT COUNT(*) FROM users WHERE email IS NULL;
244+
```
245+
246+
4. **Transaction Safety**: Consider wrapping operations in transactions where possible.
247+
248+
```sql
249+
START TRANSACTION;
250+
251+
ALTER TABLE orders
252+
ADD CONSTRAINT fk_customer FOREIGN KEY (customer_id)
253+
REFERENCES customers (id);
254+
255+
-- Validate changes or perform additional operations
256+
257+
COMMIT;
258+
-- OR ROLLBACK if needed
259+
```
260+
261+
5. **Indexes**: Consider adding indexes before foreign keys for better performance.
262+
263+
6. **Application Coordination**: Schedule constraint changes during application maintenance windows.
264+
265+
7. **Documentation**: Keep documentation of your schema constraints and their purposes.

0 commit comments

Comments
 (0)