mysql字段約束-索引-外鍵

字段修飾符 (約束)

null和not null修飾符
空和非空

mysql> create table test(id int not null,name varchar(8) not null,pass varchar(20) not null);
Query OK, 0 rows affected (0.00 sec)

創建一個表,每個字段後面跟着not null ,非空,說明這個字段不允許爲空值

插入數據測試

mysql> insert into test values(1,'dz','123456');  #正常插入數據
Query OK, 1 row affected (0.29 sec)

mysql> insert into test values(2,'zhangs',null);   #當插入的記錄有null就會報錯,約束條件已經約束
ERROR 1048 (23000): Column 'pass' cannot be null
mysql> insert into test values(3,'ls',' ');    #不允許插入null值,允許插入空格
Query OK, 1 row affected (0.00 sec)

注:NOT NULL 的字段是不能插入“NULL”的,只能插入“空值”

<null和not null區別>
1、字段類型是not null,爲什麼可以插入空值
2、爲什麼not null的效率比null高
3、判斷字段不爲空的時候,到底要 select * from table where column <> ‘’ 還是要用 select * from table where column is not null 呢。

“空值” 和 “NULL”有什麼不一樣?
1、空值是不佔用空間的
2、mysql中的NULL其實是佔用空間的,下面是來自於MYSQL官方的解釋
“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”
#“空列需要行中的額外空間來記錄其值是否爲空。對於MyISAM表,每個NULL列需要一個額外的位,四捨五入到最接近的字節。
比如:一個杯子,空值’'代表杯子是真空的,NULL代表杯子中裝滿了空氣,雖然杯子看起來都是空的,但是裏面是有空氣的。

爲什麼not null的效率比null高?
NULL 其實並不是空值,而是要佔用空間,所以mysql在進行比較的時候,NULL 會參與字段比較,所以對效率有一部分影響。
而且索引時不會存儲NULL值的,所以如果索引的字段可以爲NULL,索引的效率會下降很多。

-Mysql難以優化引用可空列查詢,它會使索引、索引統計和值更加複雜。可空列需要更多的存儲空間,還需要mysql內部進行特殊處理。可空列被索引後,每條記錄都需要一個額外的字節,還能導致MyISAM中固定大小的索引變成可變大小的索引--------這也是《高性能mysql第二版》介紹的解讀:“可空列需要更多的存儲空間”:需要一個額外字節作爲判斷是否爲NULL的標誌位“需要mysql內部進行特殊處理”

所以使用not null 比null效率高

判斷字段不爲空的時候,到底要 select * from test where pass <> ‘’ 還是要用 select * from test where pass is not null
舉例
建表

mysql> create table test(id int not null,name varchar(8) not null,pass varchar(20) not null);
Query OK, 0 rows affected (0.00 sec)

插入數據

mysql> insert into test values(1,'dz','123456');
Query OK, 1 row affected (0.29 sec)

mysql> insert into test values(2,'zhangs',null);
ERROR 1048 (23000): Column 'pass' cannot be null
mysql> insert into test values(3,'ls',' ');
Query OK, 1 row affected (0.00 sec)

查詢

mysql> select * from test;
+----+------+--------+
| id | name | pass   |
+----+------+--------+
|  1 | dz   | 123456 |
|  3 | ls   |        |
+----+------+--------+
2 rows in set (0.00 sec)
mysql> select * from test where pass <> ' '; 
+----+------+--------+
| id | name | pass   |
+----+------+--------+
|  1 | dz   | 123456 |
+----+------+--------+
1 row in set (0.00 sec)
mysql> select * from test where pass = ' ';
+----+------+------+
| id | name | pass |
+----+------+------+
|  3 | ls   |      |
+----+------+------+
1 row in set (0.03 sec)
mysql> create table test2(id varchar(4) not null,name  varchar(4) null)ENGINE=MyISAM;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test2 values (' ' , 'test');
Query OK, 1 row affected (0.00 sec)
mysql> insert into test2 values ('T' , '');
Query OK, 1 row affected (0.00 sec)
mysql> select * from test2;
+----+------+
| id | name |
+----+------+
|    | test |
| T  |      |
+----+------+
2 rows in set (0.00 sec)

mysql> select * from test2 where name <> '';
+----+------+
| id | name |
+----+------+
|    | test |
+----+------+
1 row in set (0.01 sec)

mysql> select * from test2 where name =' ';
+----+------+
| id | name |
+----+------+
| T  |      |
+----+------+
1 row in set (0.00 sec)

爲空表示不佔空間,null佔用空間

default 設定字段的默認值

爲字段指定默認的值

mysql> create table test3 (name varchar(8) not null,dept varchar(20) default 'SOS');
Query OK, 0 rows affected (0.01 sec)

創建一個表,設置一個字段默認值爲SOS

mysql> insert into test3 (name) values ('test');
Query OK, 1 row affected (0.00 sec)

mysql> select * from test3;
+------+------+
| name | dept |
+------+------+
| test | SOS  |
+------+------+
1 row in set (0.00 sec)
mysql> insert into test3 values ('tet','as');
Query OK, 1 row affected (0.01 sec)

mysql> select * from test3;
+------+------+
| name | dept |
+------+------+
| test | SOS  |
| tet  | as   |
+------+------+
2 rows in set (0.00 sec)

當默認字段沒有插入數據時,默認值是SOS,當插入有數據時,以插入的數據爲準。
如果字段沒有設定default ,mysql依據這個字段是null還是not null,如果爲可以爲null,則爲null。如果不可以爲null,報錯。。
如果時間字段,默認爲當前時間 ,插入0時,默認爲當前時間。
如果是enum 類型,默認爲第一個元素。

auto_increment字段約束

自動增長

只能修飾 int字段。 表明mysql應該自動爲該字段生成一個唯一沒有用過的數(每次在最大ID值的基礎上加1。特例:如果目前最大ID是1,然後刪除1,新添加的會是2.)。對於主鍵,這是非常 有用的。 可以爲每條記錄創建一個惟一的標識符

創建一個表,ID字段設爲int,非空,自增長,設主鍵,lable 字段 varchar 非空

mysql> create table items ( id int not null auto_increment primary key, label varchar(20) not null );
Query OK, 0 rows affected (0.01 sec)

插入數據

mysql> insert into items (label) values ('les');
Query OK, 1 row affected (0.00 sec)

mysql> select * from items;
+----+-------+
| id | label |
+----+-------+
|  1 | les   |
+----+-------+
1 row in set (0.00 sec)

mysql> insert into items (label) values ('lett');
Query OK, 1 row affected (0.00 sec)

mysql> select * from items;
+----+-------+
| id | label |
+----+-------+
|  1 | les   |
|  2 | lett  |
+----+-------+
2 rows in set (0.00 sec)

id字段一直沒有插入數據,都會自動增長,主鍵,具有唯一性

清除表中的記錄

清空表中所有記錄
方法一:delete 不加where條件,清空所有表記錄。但是delete不會清零auto_increment 值

mysql> select * from items;
+----+-------+
| id | label |
+----+-------+
|  1 | les   |
|  2 | lett  |
|  3 | lett  |
|  4 | lett  |
|  5 | lett  |
|  6 | lett  |
|  7 | lett  |
|  8 | lett  |
|  9 | lett  |
+----+-------+
9 rows in set (0.00 sec)

mysql> delete from items;
Query OK, 9 rows affected (0.00 sec)

mysql> insert into items (label) values ('lett');
Query OK, 1 row affected (0.00 sec)

mysql> select * from items;
+----+-------+
| id | label |
+----+-------+
| 10 | lett  |
+----+-------+
1 row in set (0.00 sec)

方法二:刪除表中所有記錄,清auto_increment 值。
truncate

作用: 刪除表的所有記錄,並清零auto_increment 值。新插入的記錄從1開始。
語法: truncate table name;

mysql> truncate table items;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into items (label) values ('lett');
Query OK, 1 row affected (0.00 sec)

mysql> select * from items;
+----+-------+
| id | label |
+----+-------+
|  1 | lett  |
+----+-------+
1 row in set (0.00 sec)

索引

索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分),它們包含着對數據表裏所有記錄的引用指針。更通俗的說,數據庫索引好比是一本書前面的目錄,能加快數據庫的查詢速度。
優點:爲了加快搜索速度,減少查詢時間 。
缺點:
1 索引是以文件存儲的。如果索引過多,佔磁盤空間較大。而且他影響: insert ,update ,delete 執行時間。
2索引中數據必須與數據表數據同步:如果索引過多,當表中數據更新的時候後,索引也要同步更新,這就降低了效率。

索引的類型

1、普通索引
2、唯一性索引
3、主鍵索引(主索引)
4、複合索引

普通索引

最基本的索引,不具備唯一性,就是加快查詢速度
創建普通索引:

方法一:創建表時添加索引
create table 表名(
列定義
index 索引名稱 (字段)
index 索引名稱 (字段)

注:可以使用key,也可以使用index 。index 索引名稱 (字段) ,索引名稱,可以加也可以不加,不加使用字段名作爲索引名。

mysql> create table test4 (id int(4),name varchar(20),index(name));
Query OK, 0 rows affected (0.00 sec)

mysql> desc test4;  #查看索引
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(4)      | YES  |     | NULL    |       |
| name  | varchar(20) | YES  | MUL | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
注:如果Key是MUL, 就是一般性索引,該列的值可以重複, 該列是一個非唯一索引的前導列(第一列)或者是一個唯一性索引的組成部分但是可以含有空值NULL。就是表示是一個普通索引。

mysql> show create table test4;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                       |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| test4 | CREATE TABLE `test4` (
  `id` int(4) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

普通索引,如果不指定索引名稱,會用默認字段做爲索引名稱

爲已經建好的表的某個字段添加普通索引

當表創建完成後,使用alter爲表添加索引:
alter table 表名 add index 索引名稱 (字段1,字段2…);

mysql> alter table test4 add key (id);
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> show create table test4;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                          |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| test4 | CREATE TABLE `test4` (
  `id` int(4) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  KEY `name` (`name`),
  KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

刪除普通索引

mysql> alter table test4 drop  key id;  #後面跟着的是索引名稱
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table test4;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                       |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------+
| test4 | CREATE TABLE `test4` (
  `id` int(4) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  KEY `name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> desc test4;
+-------+-------------+------+-----+---------+-------+
| Field | Type        | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+-------+
| id    | int(4)      | YES  |     | NULL    |       |
| name  | varchar(20) | YES  | MUL | NULL    |       |
+-------+-------------+------+-----+---------+-------+
2 rows in set (0.00 sec)

注:如果Key是MUL, 就是一般性索引,該列的值可以重複, 該列是一個非唯一索引的前導列(第一列)或者是一個唯一性索引的組成部分但是可以含有空值NULL。就是表示是一個普通索引。

唯一索引

與普通索引基本相同,但有一個區別:索引列的所有值都只能出現一次,即必須唯一,用來約束內容,字段值只能出現一次。應該加唯一索引。唯一性允許有NULL值<允許爲空>。
創建唯一索引:
方法一:創建表時加唯一索引
create table 表名(
列定義:
unique key 索引名 (字段);
)
注意:常用在值不能重複的字段上,比如說用戶名,電話號碼,身份證號。

mysql> create table demo(id int(4) auto_increment primary key, uName varchar(20),pwd varchar(4),unique index (uNamme));
Query OK, 0 rows affected (0.01 sec)

mysql> desc demo;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(4)      | NO   | PRI | NULL    | auto_increment |
| uName | varchar(20) | YES  | UNI | NULL    |                |
| pwd   | varchar(4)  | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

修改,需要先查看錶結構

修改表時加唯一索引
建完表增加一個唯一索引
alter table 表名 add unique 索引名 (字段);

mysql> alter table demo add unique index_pwd (pwd);
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> desc demo;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(4)      | NO   | PRI | NULL    | auto_increment |
| uName | varchar(20) | YES  | UNI | NULL    |                |
| pwd   | varchar(4)  | YES  | UNI | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)

主鍵索引

查詢數據庫,按主鍵查詢是最快的,每個表只能有一個主鍵列,可以有多個普通索引列。主鍵列要求列的所有內容必須唯一,而索引列不要求內容必須唯一,不允許爲空

mysql> create table demo1(id int(4) auto_increment primary key, uName varchar(20),pwd varchar(4));
Query OK, 0 rows affected (0.00 sec)

mysql> desc demo1;
+-------+-------------+------+-----+---------+----------------+
| Field | Type        | Null | Key | Default | Extra          |
+-------+-------------+------+-----+---------+----------------+
| id    | int(4)      | NO   | PRI | NULL    | auto_increment |
| uName | varchar(20) | YES  |     | NULL    |                |
| pwd   | varchar(4)  | YES  |     | NULL    |                |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
mysql> show index from demo1 \G
*************************** 1. row ***************************
        Table: demo1
   Non_unique: 0
     Key_name: PRIMARY
 Seq_in_index: 1
  Column_name: id
    Collation: A
  Cardinality: 0
     Sub_part: NULL
       Packed: NULL
         Null: 
   Index_type: BTREE
      Comment: 
Index_comment: 
1 row in set (0.00 sec)
mysql> show create table demo1;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                   |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| demo1 | CREATE TABLE `demo1` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `uName` varchar(20) DEFAULT NULL,
  `pwd` varchar(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

創建表後添加<不推薦>如果生產的數據無法保證唯一,創建主鍵報錯
刪除主鍵報錯,主要原因是這個字段有自增長的約束。想要刪除主鍵,要先刪除自增長的約束

mysql> alter table demo1 drop primary key;
ERROR 1075 (42000): Incorrect table definition; there can be only one auto column and it must be defined as a key
mysql> alter table demo1 change id id  int(4) not null;   先取消自增長,
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table demo1;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                    |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| demo1 | CREATE TABLE `demo1` (
  `id` int(4) NOT NULL,
  `uName` varchar(20) DEFAULT NULL,
  `pwd` varchar(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> alter table demo1 drop primary key;            刪除主鍵
Query OK, 0 rows affected (0.00 sec)
Records: 0  Duplicates: 0  Warnings: 0

添加自增長,和字段的主鍵

mysql> alter table demo1 change id id int(4) not null primary key auto_increment;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table demo1;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                   |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| demo1 | CREATE TABLE `demo1` (
  `id` int(4) NOT NULL AUTO_INCREMENT,
  `uName` varchar(20) DEFAULT NULL,
  `pwd` varchar(4) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

主鍵索引,唯一性索引區別:主鍵索引不能有NULL,唯一性索引可以有空值

複合索引

索引可以包含一個、兩個或更多個列。兩個或更多個列上的索引被稱作複合索引
就是同時有不同的條件約束在裏面

創建一個表存放服務器允許或拒絕的IP和port,要記錄中IP和port要唯一。

mysql> create table firewall ( host varchar(15) not null ,port smallint(4) not null ,access enum('deny','allow') not null, primary key (host,port)); 
Query OK, 0 rows affected (0.00 sec)

mysql> insert into firewall values('10.10.100.22',22,'deny');
Query OK, 1 row affected (0.00 sec)

mysql> insert into firewall values('10.10.100.22',23,'deny');
Query OK, 1 row affected (0.00 sec)

mysql> insert into firewall values('10.10.100.22',25,'allow');
Query OK, 1 row affected (0.01 sec)

mysql> insert into firewall values('10.10.100.22',25,'allow');
ERROR 1062 (23000): Duplicate entry '10.10.100.22-25' for key 'PRIMARY'

插入一樣就報錯,唯一

建表的時候如果加各種索引,順序如下:
create table 表名(字段定義,PRIMARYKEY (bId),UNIQUE KEY bi (bImg),KEY bn (bName),KEY ba (author))

全文索引 (FULLTEXT INDEX)

全文索引(也稱全文檢索)是目前搜索引擎使用的一種關鍵技術。它能夠利用「分詞技術「等多種算法智能分析出文本文字中關鍵字詞的頻率及重要性,然後按照一定的算法規則智能地篩選出我們想要的搜索結果
mysql 在數據量較大的情況下,高併發連接的情況下。
select 語句 where bName like ‘%網%’
使用% _ 通配符,不通過索引,直接全表掃描。
ABSUWU LIKE ‘%U_U’
全文索引會給數據庫造成很大壓力。

mysql的解決方案:全文索引:3.2開始支持全文索引。無法正確支持中文。
從MySQL 5.7.6開始 MySQL內置了ngram全文檢索插件,用來支持中文分詞
你的表當前默認的存儲引擎:

全文索引只能用在 varchar text
創建全文索引:
方法一:創建表時創建
create table 表名(
列定義,
fulltext key 索引名 (字段);

方法二:修改表時添加
alter table 表名 add fulltext 索引名 (字段);
ALTER TABLE books ADD FULLTEXT [索引名] (author )
強烈注意:MySQL自帶的全文索引只能用於數據庫引擎爲MyISAM的數據表,如果是其他數據引擎,則全文索引不會生效
一般交給第三方軟件進行全文索引
http://sphinxsearch.com/

很少使用全文索引

索引設計原則:

1、索引並非越多越好
2、數據量不大不需要建立索引
3、列中的值變化不多不需要建立索引 row id
4、經常排序(order by 字段)和分組(group by 字段)的列需要建立索引
select a.bTypeId,(select b.bTypeName from category b where a.bTypeId = b.bTypeId) bn,count(*) from books a group by bTypeId;
5、唯一性約束對應使用唯一性索引
Table (id pri,use,name index,pass)

外鍵約束

什麼是外鍵約束:
foreign key就是表與表之間的某種約定的關係,由於這種關係的存在,我們能夠讓表與表之間的數據,更加的完整,關連性更強。
關於完整性,關連性我們舉個例子
有二張表,一張是用戶表,一張是訂單表:
1》如果我刪除了用戶表裏的用戶,那麼訂單表裏面與這個用戶有關的數據,就成了無頭數據了,不完整了。
2》如果我在訂單表裏面,隨便插入了一條數據,這個訂單在用戶表裏面,沒有與之對應的用戶。這樣數據也不完整了。
如果有外鍵的話,就方便多了,可以不讓用戶刪除數據,或者刪除用戶的話,通過外鍵同樣刪除訂單表裏面的數據,這樣也能讓數據完整。
創建外鍵約束:
外鍵: 每次插入或更新時,都會檢查數據的完整性。
方法一:通過create table創建外鍵
語法:
create table 數據表名稱(
…,
[CONSTRAINT [約束名稱]] FOREIGN KEY [外鍵字段]
REFERENCES [外鍵表名] (外鍵字段,外鍵字段2……)
[ON DELETE CASCADE ]
[ON UPDATE CASCADE ]
)
關於參數的解釋:
RESTRICT: 拒絕對父表的刪除或更新操作。
CASCADE: 從父表刪除或更新且自動刪除或更新子表中匹配的行。ON DELETE CASCADE和ON UPDATE CASCADE都可用
注意:on update cascade是級聯更新的意思,on delete cascade是級聯刪除的意思,意思就是說當你更新或刪除主鍵表,那外鍵表也會跟隨一起更新或刪除。

精簡化後的語法:
語法:foreign key 當前表的字段 references 外部表名 (關聯的字段) ENGINE =innodb

注:創建成功,必須滿足以下4個條件:
1、確保參照的表和字段存在。
2、組成外鍵的字段被索引。
3、必須使用ENGINE指定存儲引擎爲:innodb.
4、外鍵字段和關聯字段,數據類型必須一致。
例子:我們創建一個數據庫,包含用戶信息表和訂單表

第一張表

mysql> create table `user`(id int(11) not null auto_increment, name varchar(50) not null default '', sex int(1) not null default '0', primary key(id))ENGINE=innodb;
Query OK, 0 rows affected (0.06 sec)

#創建時,如果表名是sql關鍵字,使用時,需要使用反引號,``user是mysql保留的關鍵字,所以需要用反引號
第二張表

mysql>  create table `order`(o_id int(11) auto_increment, u_id int(11) default '0', username varchar(50), money int(11), primary key(o_id), index(u_id), foreign key order_f_key(u_id) references user(id) on delete cascade on update cascade) ENGINE=innodb;
Query OK, 0 rows affected (0.00 sec)

foreign key order_f_key(u_id) references user(id) 就是用當前的u_id 關聯 第一張表的id字段
on delete cascade on update cascade) 做了級聯更新和級聯刪除
引擎是innodb

外鍵字段和關聯字段,數據類型必須一致。

插入測試數據

mysql> insert into user(name,sex)values('HA',1),('LB',2),('HPC',1);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql>  insert into `order` (u_id,username,money)values(1,'HA',234),(2,'LB',146),(3,'HPC',256);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0
mysql> select * from user;
+----+------+-----+
| id | name | sex |
+----+------+-----+
|  1 | HA   |   1 |
|  2 | LB   |   2 |
|  3 | HPC  |   1 |
+----+------+-----+
3 rows in set (0.00 sec)
mysql> select * from `order`;
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
|    1 |    1 | HA       |   234 |
|    2 |    2 | LB       |   146 |
|    3 |    3 | HPC      |   256 |
+------+------+----------+-------+
3 rows in set (0.00 sec)

測試級聯刪除:

mysql> delete from user where id=1;
Query OK, 1 row affected (0.04 sec)

mysql> select * from `order`;
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
|    2 |    2 | LB       |   146 |
|    3 |    3 | HPC      |   256 |
+------+------+----------+-------+
2 rows in set (0.00 sec)

測試級聯更新:
更新前數據狀態

mysql> update user set id=6 where id=2;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from user;
+----+------+-----+
| id | name | sex |
+----+------+-----+
|  3 | HPC  |   1 |
|  6 | LB   |   2 |
+----+------+-----+
2 rows in set (0.00 sec)
mysql> select * from `order`;
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
|    2 |    6 | LB       |   146 |
|    3 |    3 | HPC      |   256 |
+------+------+----------+-------+
2 rows in set (0.00 sec)
mysql>  insert into `order` (u_id,username,money)values(5,'Find',346);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`app`.`order`, CONSTRAINT `order_ibfk_1` FOREIGN KEY (`u_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

這個報錯說,這個表設置了級聯更新級聯刪除,在order裏面插入一條數據u_id爲5用戶,在user表裏面根本沒有,所以插入不進去

測試數據完整性
外鍵約束,order表受user表的約束

mysql>  insert into user values(5,'Find',1);
Query OK, 1 row affected (0.00 sec)

在用戶表新增一個,在插入數據就可以成功。

mysql>  insert into `order` (u_id,username,money)values(5,'Find',346);
Query OK, 1 row affected (0.01 sec)
mysql> select * from `order`;
+------+------+----------+-------+
| o_id | u_id | username | money |
+------+------+----------+-------+
|    2 |    6 | LB       |   146 |
|    3 |    3 | HPC      |   256 |
|    5 |    5 | Find     |   346 |
+------+------+----------+-------+
3 rows in set (0.00 sec)

mysql> select * from user;
+----+------+-----+
| id | name | sex |
+----+------+-----+
|  3 | HPC  |   1 |
|  5 | Find |   1 |
|  6 | LB   |   2 |
+----+------+-----+
3 rows in set (0.00 sec)

方法二:通過alter table 創建外鍵和級聯更新,級聯刪除
語法:
alter table 數據表名稱 add
[constraint [約束名稱] ] foreign key (外鍵字段,…) references 數據表(參照字段,…)
[on update cascade|set null|no action]
[on delete cascade|set null|no action]
)
查看創建表的詳情

mysql> show create table `order`;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                                                                                                                                                                                                                                                                                               |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| order | CREATE TABLE `order` (
  `o_id` int(11) NOT NULL AUTO_INCREMENT,
  `u_id` int(11) DEFAULT '0',
  `username` varchar(50) DEFAULT NULL,
  `money` int(11) DEFAULT NULL,
  PRIMARY KEY (`o_id`),
  KEY `u_id` (`u_id`),
  CONSTRAINT `order_ibfk_1`(外鍵名稱) FOREIGN KEY (`u_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

刪除外鍵
語法
alter table 數據表名稱 drop foreign key 約束(外鍵)名稱

mysql> alter table `order` drop foreign key  order_ibfk_1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0

表要寫外鍵所在的表

視圖

什麼是視圖
視圖就是一個存在於數據庫中的虛擬表。1
視圖本身沒有數據,只是通過執行相應的select語句完成獲得相應的數據。

我們在怎樣的場景使用它,爲什麼使用視圖
如果某個查詢結果出現的非常頻繁,也就是,要經常拿這個查詢結果來做子查詢這種
1.視圖能夠簡化用戶的操作
視圖機制用戶可以將注意力集中在所關心的數據上。如果這些數據不是直接來自基本表,則可以通過定義視圖,使數據庫看起來結構簡單、清晰,並且可以簡化用戶的數據查詢操作
2.視圖是用戶能以不同的角度看待同樣的數據。
對於固定的一些基本表,我們可以給不同的用戶建立不同的視圖,這樣不同的用戶就可以看到自己需要的信息了。
3.視圖對重構數據庫提供了一定程度的邏輯性。
比如原來的A表被分割成了B表和C表,我們仍然可以在B表和C表的基礎上構建一個視圖A,而使用該數據表的程序可以不變。
4.視圖能夠對機密數據提供安全保護
比如說,每門課的成績都構成了一個基本表,但是對於每個同學只可以查看自己這門課的成績,因此可以爲每個同學建立一個視圖,隱藏其他同學的數據,只顯示該同學自己的
5.適當的利用視圖可以更加清晰的表達查詢數據。
有時用現有的視圖進行查詢可以極大的減小查詢語句的複雜程度。

創建視圖

語法:create view視圖名稱(即虛擬的表名) as select 語句。
相當於linux的別名
主要就是將一長串的select語句查詢的結果賦值給試圖

我們在book數據庫中操作
mysql> create view bc as select b.bName ,b.price ,c.bTypeName from books as b left join category as c on b.bTypeId=c.bTypeId ;
可以按照普通表去訪問。
另外視圖表中的數據和原數據表中數據是同步的。
查看視圖創建信息:
mysql> show create view bc \G
在這裏插入圖片描述
查詢視圖中的數據
在這裏插入圖片描述
更新或修改視圖
語法:
alter view視圖名稱(即虛擬的表名) as select 語句。
update view視圖名稱(即虛擬的表名)set
mysql> alter view bc as select b.bName ,b.publishing ,c.bTypeId from books as b left join category as c on b.bTypeId=c.bTypeId ;
在這裏插入圖片描述
更新
mysql> update bc set bName=‘HA’ where price=34;
在這裏插入圖片描述
刪除視圖
drop view 視圖名。
mysql> drop view bc;
學習mysql 先搞懂它的概念原理,慢慢做實驗理解它真正的用法,然後結合實際爲什麼要用這個sql寫法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章