wordpress常見的15個問題鄭州seo優(yōu)化外包公司
1.約束類型
類型 | 說明 |
NOT NULL非空約束 | 指定非空約束的列不能存儲NULL值 |
DEFAULT默認約束 | 當(dāng)沒有給列賦值時使用的默認值 |
UNIQUE唯一約束 | 指定唯一約束的列每行數(shù)據(jù)必須有唯一的值 |
PRIMARY KEY主鍵約束 | NOT NULL和UNIQUE的結(jié)合,可以指定一個列霍多個列,有助于防止數(shù)據(jù)重復(fù)和提高數(shù)據(jù)的查詢性能 |
FOREIGN KEY外鍵約束 | 外鍵約束是一種關(guān)系約束,用于定義兩個表之間的關(guān)聯(lián)關(guān)系,可以確保數(shù)據(jù)的完整性和一致性 |
CHECK約束 | 用于限制列或數(shù)據(jù)在數(shù)據(jù)庫表中的值,確保數(shù)據(jù)的準(zhǔn)確性和可靠性 |
2.NOT NULL非空約束
定義表時某列不允許為NULL時,可以為列添加非空約束
?如創(chuàng)建?個學(xué)?表,學(xué)?名為NULL時,這條記錄是不完整的
drop table if exists student;
create table student(id bigint,name varchar(20)
);# 插?數(shù)據(jù)
insert into student values (1, null);# 查詢
select * from student;
+------+------+
| id | name |
+------+------+
| 1 | NULL | # 班級名為NULL,沒有意義
+------+------+
1 row in set (0.00 sec)
此時需要約束學(xué)生名的列不能為NULL
drop table if exists student;
# 為所有列添加?空約束
create table student (id bigint,name varchar(20) NOT NULL
);# 由于name列有?空約束,插?NULL值時報錯
insert into student values (1, null);
ERROR 1048 (23000): Column 'name' cannot be null# 正常值可以成功插?
insert into student values (1, '張三');
Query OK, 1 row affected (0.00 sec)
select * from student;
+------+--------+
| id | name |
+------+--------+
| 1 | 張三 |
+------+--------+
1 row in set (0.00 sec)
查看表結(jié)構(gòu),NULL列為NO表?值不允許為NULL,YES表?值可以為NULL
desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | bigint | YES | | NULL | |
| name | varchar(10) | NO | | NULL | |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
3.DEFALUT默認值約束
DEFAULT 約束?于向列中插?默認值,如果沒有為列設(shè)置值,那么會將默認值設(shè)置到該列
重構(gòu)學(xué)?表,新增年齡列
drop table student;
# 創(chuàng)建學(xué)?表,加?年齡列
create table student (id bigint,name varchar(20) not null,age int
);
插??條記錄,沒有設(shè)置默認約束時,不指定年齡的值時列為NULL
insert into student(id, name) values (1, '張三');select * from student;
+------+--------+------+
| id | name | age |
+------+--------+------+
| 1 | 張三 | NULL | # 年齡值為NULL
+------+--------+------+
1 row in set (0.00 sec)
重構(gòu)學(xué)?表,為年齡的列加?默認約束
drop table student;# 為年齡列加?默認約束create table student (id bigint,name varchar(20) not null,age int DEFAULT 18
);
插??條記錄,不指定年齡的值時列使?了默認值
select * from student;
+------+--------+------+
| id | name | age |
+------+--------+------+
| 1 | 張三 | 18 |
+------+--------+------+
1 row in set (0.00 sec)
查看表結(jié)構(gòu),年齡列的默認值為18
desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | bigint | YES | | NULL | |
| name | varchar(20) | NO | | NULL | |
| age | int | YES | | 18 | |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
當(dāng)手動明確值年齡列為NULL時列值為NULL
insert into student(id, name, age) values (2, '李四', NULL);
Query OK, 1 row affected (0.00 sec)
select * from student;
+------+--------+------+
| id | name | age |
+------+--------+------+
| 1 | 張三 | 18 |
| 2 | 李四 | NULL |
+------+--------+------+
2 rows in set (0.00 sec)
4.UNIQUE唯一約束
指定了唯?約束的列,該列的值在所有記錄中不能重復(fù),?如?個?的?份證號,學(xué)?的學(xué)號等
重構(gòu)學(xué)生表,新增學(xué)號列
drop table student;
# 學(xué)號列設(shè)置唯?約束
create table student (id bigint,name varchar(20) not null,age int DEFAULT 18,sno varchar(10)
);
不設(shè)置唯?約束時,學(xué)號可以重復(fù)
insert into student(id, name, sno) values (1, '張三', '100001');
Query OK, 1 row affected (0.00 sec)insert into student(id, name, sno) values (2, '李四', '100001');
Query OK, 1 row affected (0.00 sec)select * from student;
+------+--------+------+--------+
| id | name | age | sno |
+------+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 李四 | 18 | 100001 |
+------+--------+------+--------+
2 rows in set (0.00 sec)
重構(gòu)學(xué)?表,為學(xué)號列設(shè)置唯?約束
drop table student;
create table student (id bigint,name varchar(20) not null,age int DEFAULT 18,sno varchar(10) UNIQUE # 唯?約束
);
插?重復(fù)的學(xué)號時報錯,唯?約束?效
insert into student(id, name, sno) values (1, '張三', '100001');
Query OK, 1 row affected (0.01 sec)insert into student(id, name, sno) values (2, '李四', '100001');
ERROR 1062 (23000): Duplicate entry '100001' for key 'student.sno'select * from student;
+------+--------+------+--------+
| id | name | age | sno |
+------+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
+------+--------+------+--------+
1 row in set (0.00 sec)
查看表結(jié)構(gòu),Key列顯?UNI表?唯?約束
desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | bigint | YES | | NULL | |
| name | varchar(20) | NO | | NULL | |
| age | int | YES | | 18 | |
| sno | varchar(10) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
5.PRIMARY KEY主鍵約束
主鍵約束唯?標(biāo)識數(shù)據(jù)庫表中的每條記錄。主鍵必須包含唯?的值,且不能包含 NULL 值。每個表只能有?個主鍵,可以由單個列或多個列組成。通常為每張表都指定?個主鍵,主鍵列建議使?BIGINT類型
?重構(gòu)學(xué)?表,為ID列添加?空和唯?約束
drop table student;
create table student (id bigint not null unique,name varchar(20) not null,age int DEFAULT 18,sno varchar(10) UNIQUE
);
查看表結(jié)構(gòu),添加了?空和唯?約束之后Key列顯?PRI表?主鍵
desc student;
+-------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id | bigint | NO | PRI | NULL | | # 主鍵
| name | varchar(20) | NO | | NULL | |
| age| int | YES | | 18 | |
| sno| varchar(10) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+-------+
4 rows in set (0.00 sec)
當(dāng)Id列的重復(fù)時會發(fā)?主鍵沖突
insert into student(id, name, sno) values (1, '張三', '100001');
Query OK, 1 row affected (0.01 sec)insert into student(id, name, sno) values (1, '李四', '100001');
ERROR 1062 (23000): Duplicate entry '1' for key 'student.id'
通常把主鍵列設(shè)置為?動增?,讓數(shù)據(jù)庫維護主鍵值
drop table student;# 重構(gòu)學(xué)?表
create table student (id bigint PRIMARY KEY auto_increment, # 設(shè)置?增主鍵name varchar(20) not null,age int DEFAULT 18,sno varchar(10) UNIQUE
);
插?數(shù)據(jù)時不設(shè)置主鍵列的值
# 主鍵列的值為NULL
insert into student(id, name, sno) values (NULL, '張三', '100001');
Query OK, 1 row affected (0.00 sec)# 不指定主鍵
insert into student(name, sno) values ('李四', '100002');
Query OK, 1 row affected (0.01 sec)# 主鍵列的值?動?成
select * from student;
+----+--------+------+--------+
| id | name | age | sno |
+----+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 李四 | 18 | 100002 |
+----+--------+------+--------+
2 rows in set (0.00 sec)
查看表結(jié)構(gòu),Extra列顯?auto_increment 表??增
desc student;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
| age | int | YES | | 18 | |
| sno | varchar(10) | YES | UNI | NULL | |
+-------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
如果某條記錄寫?失敗,新?成的主鍵值將會作廢
# 由于學(xué)號重復(fù),產(chǎn)?了唯?沖突,導(dǎo)致插?失敗,ID為3的主鍵值作廢
insert into student(name, sno) values ('王五', '100002');
ERROR 1062 (23000): Duplicate entry '100002' for key 'student.sno'# 修改學(xué)號后成功插?數(shù)據(jù)
insert into student(name, sno) values ('王五', '100003');
Query OK, 1 row affected (0.00 sec)# 查詢后發(fā)現(xiàn)新記錄ID列的值為4
select * from student;
+----+--------+------+--------+
| id | name | age | sno |
+----+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 王五 | 18 | 100002 |
| 4 | 王五 | 18 | 100003 | # 新插?的記錄
+----+--------+------+--------+
3 rows in set (0.00 sec)
主鍵值可以不連續(xù)
# ?動指定?個值
insert into student(id, name, sno) values (100, '趙六', '100004');
Query OK, 1 row affected (0.01 sec)select * from student;
+-----+--------+------+--------+
| id | name | age | sno |
+-----+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 王五 | 18 | 100002 |
| 4 | 王五 | 18 | 100003 |
| 100 | 趙六 | 18 | 100004 |
+-----+--------+------+--------+
4 rows in set (0.00 sec)# 下?次?增從主鍵的最?值開始
insert into student(name, sno) values ('錢七', '100005');
Query OK, 1 row affected (0.01 sec)select * from student;
+-----+--------+------+--------+
| id | name | age | sno |
+-----+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 王五 | 18 | 100002 |
| 4 | 王五 | 18 | 100003 |
| 100 | 趙六 | 18 | 100004 |
| 101 | 錢七 | 18 | 100005 | # ID列的值是101
+-----+--------+------+--------+
5 rows in set (0.00 sec)
主鍵或唯?鍵沖突時的更新操作,插?否則更新
# 語法
INSERT ... ON DUPLICATE KEY UPDATE column = value [, column = value] ...# 插?ID為100,學(xué)號為100100的學(xué)?記錄時,報主鍵沖突
insert into student(id, name, sno) values (100, '趙六', '100100');
ERROR 1062 (23000): Duplicate entry '100' for key 'student.PRIMARY'# 可以使?以上語法,如果插?時有沖突則更新當(dāng)前列的值
insert into student(id, name, sno) values (100, '趙六', '100100')-> ON DUPLICATE KEY UPDATE name = '趙六', sno = '100100';
Query OK, 2 rows affected (0.01 sec) # 兩?受影響,表?刪除了原來的記錄,?新寫?了?條記錄
# 與update student set name = '趙六', sno = '100100' where id = 100; 等效select * from student;
+-----+--------+------+--------+
| id | name | age | sno |
+-----+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 王五 | 18 | 100002 |
| 4 | 王五 | 18 | 100003 |
| 100 | 趙六 | 18 | 100100 | # 學(xué)號已修改
| 101 | 錢七 | 18 | 100005 |
+-----+--------+------+--------+
5 rows in set (0.00 sec)
替換,如果存在沖突則替換,不存在沖突則插?
# 語法
REPLACE [INTO] table_name[(column [, column] ...)]
VALUES(value_list) [, (value_list)] ...
value_list: value, [, value] ...# 寫?或更新Id為101的記錄
REPLACE into student(id, name, sno) values (101, '錢七', '100101');
Query OK, 2 rows affected (0.01 sec) # 受影響兩?# 原數(shù)據(jù)已更新
select * from student;
+-----+--------+------+--------+
| id | name | age | sno |
+-----+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 王五 | 18 | 100002 |
| 4 | 王五 | 18 | 100003 |
| 100 | 趙六 | 18 | 100100 |
| 101 | 錢七 | 18 | 100101 |
+-----+--------+------+--------+
5 rows in set (0.00 sec)# 寫??條新數(shù)據(jù)
REPLACE into student(id, name, sno) values (102, '吳?', '100102');
Query OK, 1 row affected (0.01 sec) # 受影響??# 成功寫?
select * from student;
+-----+--------+------+--------+
| id | name | age | sno |
+-----+--------+------+--------+
| 1 | 張三 | 18 | 100001 |
| 2 | 王五 | 18 | 100002 |
| 4 | 王五 | 18 | 100003 |
| 100 | 趙六 | 18 | 100100 |
| 101 | 錢七 | 18 | 100101 |
| 102 | 吳? | 18 | 100102 |
+-----+--------+------+--------+
6 rows in set (0.00 sec)
表中不能有多個主鍵
drop table student;
# 重構(gòu)學(xué)?表
create table student (id bigint PRIMARY KEY auto_increment, # 定義主鍵name varchar(20) PRIMARY KEY # 定義主鍵
);
ERROR 1068 (42000): Multiple primary key defined # 報錯
復(fù)合主鍵:由多個列共同組成的主鍵,主鍵是否沖突以多個列的組成進?判定
drop table student;
# 重構(gòu)學(xué)?表
create table student (id bigint,name varchar(20),PRIMARY KEY (id, name) # 指定復(fù)合主鍵
);# 插?數(shù)據(jù)
insert into student(id, name) values (1, '張三');
Query OK, 1 row affected (0.01 sec)# 重復(fù)插?主鍵沖突,此時主鍵值由id和name兩個列共同決定
insert into student(id, name) values (1, '張三');
ERROR 1062 (23000): Duplicate entry '1-張三' for key 'student.PRIMARY'# 修改id值插?成功
insert into student(id, name) values (2, '張三');
Query OK, 1 row affected (0.00 sec)select * from student;
+----+--------+
| id | name |
+----+--------+
| 1 | 張三 |
| 2 | 張三 |
+----+--------+
2 rows in set (0.00 sec)
6.FOREIGN KEY外鍵約束
外鍵?于定義主表和從表之間的關(guān)系外鍵約束主定義在從表的列上,主表關(guān)聯(lián)的列必須是主鍵或唯?約束當(dāng)定義外鍵后,要求從表中的外鍵列數(shù)據(jù)必須在主表的主鍵或唯?列存在或為null。
?
?創(chuàng)建班級表(主表),并初始化數(shù)據(jù)
drop table if exists class;
# 建表
create table class (id bigint primary key auto_increment,name varchar(20) not null
);# 初始化數(shù)據(jù)
insert into class (name) values ('java01'), ('java02'), ('java03'), ('C++01'),
('C++02');
Records: 5 Duplicates: 0 Warnings: 0select * from class;
+----+--------+
| id | name |
+----+--------+
| 1 | java01 |
| 2 | java02 |
| 3 | java03 |
| 4 | C++01 |
| 5 | C++02 |
+----+--------+
5 rows in set (0.00 sec)
重構(gòu)學(xué)生表(從表),加入外鍵約束
# 語法
foreign key (id) references class(id)drop table if exists student;# 重構(gòu)表
create table student(id bigint PRIMARY KEY auto_increment, name varchar(20) not null,age int DEFAULT 18,class_id bigint,foreign key (class_id) references class(id) # 創(chuàng)建外鍵約束
);
查看表結(jié)構(gòu),Key列的值為MUL表?外鍵約束的列
desc student;
+----------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+----------------+
| id | bigint | NO | PRI | NULL | auto_increment |
| name | varchar(20) | NO | | NULL | |
| age | int | YES | | 18 | |
| class_id | bigint | YES | MUL | NULL | |
+----------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
正常插?數(shù)據(jù)
# 班級編號在主表中存在
insert into student(name, class_id) values ('張三', 1), ('李四', 2);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0# 插?成功
select * from student;
+----+--------+------+----------+
| id | name | age | class_id |
+----+--------+------+----------+
| 1 | 張三 | 18 | 1 |
| 2 | 李四 | 18 | 2 |
+----+--------+------+----------+
2 rows in set (0.00 sec)
插??個班級號為100的學(xué)?,由于主表中沒有這個班級,插?失敗
# 班級編號在主表中不存在,提?外鍵約束限制導(dǎo)致插?失敗
insert into student(name, class_id) values ('王五', 100);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint
fails (`java01`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY
(`class_id`) REFERENCES `class` (`id`))
插?班級Id為NULL的記錄,可以成功,表?當(dāng)前學(xué)?還沒有分配置班級
# 班級為NULL
insert into student(name, class_id) values ('王五', NULL);
Query OK, 1 row affected (0.00 sec)
select * from student;
+----+--------+------+----------+
| id | name | age | class_id |
+----+--------+------+----------+
| 1 | 張三 | 18 | 1 |
| 2 | 李四 | 18 | 2 |
| 4 | 王五 | 18 | NULL |
+----+--------+------+----------+
3 rows in set (0.00 sec)
刪除主表某條記錄時,從表中不能有對該記錄的引?
# 刪除從表中沒有引?的記錄,可以成功
delete from class where name = 'java03';
Query OK, 1 row affected (0.00 sec)select * from class;
+----+--------+
| id | name |
+----+--------+
| 1 | java01 |
| 2 | java02 |
| 4 | C++01 |
| 5 | C++02 |
+----+--------+
4 rows in set (0.00 sec)# 刪除從表中引?的記錄,失敗
delete from class where name = 'java01';
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key
constraint fails (`java01`.`student`, CONSTRAINT `student_ibfk_1` FOREIGN KEY
(`class_id`) REFERENCES `class` (`id`))
刪除主表時要先刪除從表
# 從表存在是不能刪除主表
drop table class;
ERROR 3730 (HY000): Cannot drop table 'class' referenced by a foreign key
constraint 'student_ibfk_1' on table 'student'.# 刪除從表
drop table student;
Query OK, 0 rows affected (0.02 sec)# 再刪除主表,成功
drop table class;
Query OK, 0 rows affected (0.01 sec)
7.CHECK約束
可以應(yīng)?于?個或多個列,?于限制列中可接受的數(shù)據(jù)值,從?確保數(shù)據(jù)的完整性和準(zhǔn)確性。在8.0.16開始全??持CHECK約束,之前的版本會忽略CHECK的定義
重構(gòu)學(xué)?表,有以下要求,年齡不能?于16歲,性別只能是男或?
drop table if exists student;# 加?CHECK約束
create table student(id bigint PRIMARY KEY auto_increment, # 設(shè)置?增主鍵name varchar(20) not null,age int DEFAULT 18,gender char(1),check (age >= 16),check (gender = '男' or gender = '?')
);# 正常插?數(shù)據(jù)
mysql> insert into student(name, age, gender) values ('張三', 17, '男'), ('李
四', 19, '?');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0mysql> select * from student;
+----+--------+------+--------+
| id | name | age | gender |
+----+--------+------+--------+
| 1 | 張三 | 17 | 男 |
| 2 | 李四 | 19 | ? |
+----+--------+------+--------+
2 rows in set (0.00 sec)# 插?年齡?于16歲的記錄,失敗
mysql> insert into student(name, age, gender) values ('張三', 15, '男');
ERROR 3819 (HY000): Check constraint 'student_chk_1' is violated.# 插?性別的值不是男或?的記錄,失敗
mysql> insert into student(name, age, gender) values ('張三', 17, '1');
ERROR 3819 (HY000): Check constraint 'student_chk_2' is violated.
創(chuàng)建新表,c1的值不能為0,c2的值必須?于0,c3的值不?于c2
# 列與列之間也可以?較,需要在單獨??中定義
create table t_check (c1 int check(c1 <> 0),c2 int check(c2 > 0),c3 int,check(c3 >= c2)
);# 插?正常數(shù)據(jù)
mysql> insert into t_check values (-1, 3, 10);
Query OK, 1 row affected (0.01 sec)mysql> select * from t_check;
+------+------+------+
| c1 | c2 | c3 |
+------+------+------+
| -1 | 3 | 10 |
+------+------+------+
1 row in set (0.00 sec)# c1 = 0時,失敗
mysql> insert into t_check values (0, 5, 6);
ERROR 3819 (HY000): Check constraint 't_check_chk_1' is violated.# c2 <= 0時,失敗
mysql> insert into t_check values (2, -10, 10);
ERROR 3819 (HY000): Check constraint 't_check_chk_2' is violated.# c3 < c2時,失敗
mysql> insert into t_check values (2, 10, 9);
ERROR 3819 (HY000): Check constraint 't_check_chk_3' is violated.