1.創(chuàng)建數(shù)據(jù)表---基礎(高手跳過)
正統(tǒng)方法:create [TEMPORARY] table 表名 [if not exists]
(創(chuàng)建的列項定義)
[表的選項]
[分區(qū)的選項];#正統(tǒng)的創(chuàng)建方式,具體的參數(shù),請參考mysql手冊,在這里不做詳細的解釋,只說一些比較特別的。
例:
復制代碼代碼如下:
create table user(id int unsigned not null auto_increment,
username char(15),
sex enum('M','F') default 'M',
userid varchar(20),
PRIMARY KEY(id,userid),
INDEX idx_user(userid),
)engine='innodb' charset=utf8;
復制數(shù)據(jù)庫結(jié)構(gòu):
復制代碼代碼如下:
create [temporary] table 表名 [if not exists] like 已存在的表名;//模仿已存在的表創(chuàng)建一個結(jié)構(gòu)完全相同的表
mysql>create table vip_user like user;
mysql>create table vip_user select * from user where 0;//上例還可以這樣做,僅復制結(jié)構(gòu)
復制并copy數(shù)據(jù)庫
復制代碼代碼如下:
create [temporary] table 新表名 select * from 舊表名;#用戶可以人為的指定后續(xù)select組合成需要的語句。
create table dst_tbl(
id int not null auto_increment,
primary key(id)
) select a,b,c from src_tbl;
以此來創(chuàng)建各種各樣的符合用戶要求的數(shù)據(jù)庫,這里只是做一個拋磚引玉。
2.查看修改的數(shù)據(jù)表結(jié)構(gòu)
復制代碼代碼如下:
mysql> desc 數(shù)據(jù)表名;#查看數(shù)據(jù)表的結(jié)構(gòu)
mysql> show create table 數(shù)據(jù)表名\G #查看數(shù)據(jù)表的構(gòu)成語句,\G和;的意義相同,只不過\G是縱向顯示,這樣看的更清楚。
mysql> show table status like '數(shù)據(jù)表名'\G #查看數(shù)據(jù)表的狀態(tài)
mysql> show columns from 數(shù)據(jù)表名;#查看數(shù)據(jù)表的結(jié)構(gòu),同desc一樣,不過使用這條語句后面加like '字段'可以只顯示指定字段
3. 更改變據(jù)庫的結(jié)構(gòu)
我們首先創(chuàng)建一個表
mysql> create table vip(id int null,username varchar(30));
修改表結(jié)構(gòu)中的數(shù)據(jù)類型
復制代碼代碼如下:
mysql>alter table vip modify id smallint default 1;#更改數(shù)據(jù)記錄為1.
mysql>#alter table vip modify id smallint auto_increment;#大家執(zhí)行一下這句話會提示錯誤,因為mysql中要求自動增長的列設為主鍵
mysql>alter table vip add primary(id);#設vip中的值的主鍵為id,執(zhí)行這條語句后再執(zhí)行上面的就沒問題了。
mysql>alter table vip modify username char(30) not null;#改變vip的username為char(30);
mysql>alter table vip modify username mediumtext first; #改變vip中的username,并將它設在最前面字段,還有一個是after 字段,是指放在某字段后
對已有表新增字段
mysql> alter table vip add sex enum('M','F') default 'M' not null after id;#新增sex字段為enum類型,放在id的后面.
對已有字段改名
mysql>alter table vip change sex usersex tinyint default 0 not null after username;改名字段sex為usersex并改變類型和位置。
注:僅alter中modify,change很相似,但是modify不能改名只能改結(jié)構(gòu),但change即可以改名,也可以改類型。
刪除字段
mysql>alter table vip drop usersex;#刪除 usersex字段,警告,所有的該字段數(shù)據(jù)都會丟失。
數(shù)據(jù)庫改名
mysql>alter table vip rename to vip_user;數(shù)據(jù)庫進行改名。
改變數(shù)據(jù)表引擎
mysql>alter table vip engine="MyISAM";
注意,修改數(shù)據(jù)結(jié)構(gòu)是一個很危險的事,最好做好備份,以防不側(cè)。
還有部分的alter的語句和技巧我們將在以后涉及處一一到來.....
4. 關(guān)于數(shù)據(jù)約束
數(shù)據(jù)約束在mysql5中支持的越來越好了,但是現(xiàn)有的數(shù)據(jù)約束僅限于innodb,傳說中mysql5.2也會支持對數(shù)據(jù)約束的支持(期待..)
首先我們了解一下什么是數(shù)據(jù)約束,因為我們平常創(chuàng)建表中都可能會有互相關(guān)聯(lián)的信息,而數(shù)據(jù)約束是將兩個表進行關(guān)聯(lián)的一種紐帶。
例如:兩個表,一個usertype,一為userid,usertype中有一個關(guān)鍵字key為用戶類型編號,userid表中也有一 user_key對應著usertype表中的
1.首先我們要保證userid表中的所有值都在usertype中
2.其次我們要保證usertype中的值key進行改變userid表中的user_key值也會變化。
3.usertype中的值不能隨意刪除,除非userid表中不存在該usertype類型的值,如果要強制刪除則會刪除userid中的所有 usertype的值。
如果沒有數(shù)據(jù)約束,我們每次insert/update可能要用數(shù)條語句才能保證數(shù)據(jù)的正確完整性,如果使用數(shù)據(jù)約束則只需要在定義的時候進行一下處理,而不用擔心太多。而且最重要的是使用數(shù)據(jù)約束能夠很好的保證數(shù)據(jù),業(yè)務的完整性。
呵呵,說了這么多,還沒有說數(shù)據(jù)約束的缺點:慢,使用數(shù)據(jù)約束要比不使用數(shù)據(jù)約束慢得多,而且用戶每次插入數(shù)據(jù)或更改數(shù)據(jù),數(shù)據(jù)庫系統(tǒng)都會花一定的時間進行一定的檢查.但是隨著 mysql的日益成熟,這種速度會有著很大的改進。
就個人而言,我覺得非商務、實時系統(tǒng)對數(shù)據(jù)業(yè)務完整性要求較高的情況下使用數(shù)據(jù)約束還是很有必要的。其它情況下就仁者見仁智者見智了。
5.數(shù)據(jù)約束簡明解析
所以外鍵的定義必須必須滿足以下三種情況:
1.兩個表必須是innodb表類型
2.指定為外鍵的列必須進行索引
3.兩個表中關(guān)聯(lián)的外鍵類型必須相符。
我們先來看例子,在例子中進行學習:
mysql> create table parent(id int null,primary key(id)) engine=innodb; #創(chuàng)建一個主表
mysql> create table child(id int,parent_id int,
foreign key(parent_id)
references parent(id) on delete restrict on update cascade
) engine=innodb; #創(chuàng)建一個從表,并約外鍵關(guān)鍵字為parent_id,建立之間的關(guān)聯(lián)關(guān)系。
mysql> insert into parent values(1),(2),(3);#對主表插入數(shù)據(jù)
mysql> insert into child values(1,1),(1,2),(1,3);#對子表進行插入數(shù)據(jù),對應不同的parent_id子child的id值均為1;
mysql> #insert into child values(1,1),(1,2),(1,3),(1,4); #看一下這會發(fā)生什么?報錯是吧?什么原因?大家想想
說明:因為我們在創(chuàng)建語句的時候就約定了數(shù)據(jù)是進行外鍵關(guān)聯(lián)的,而parent中不存在id值為4的主鍵,那么子鍵當然更新不了了。
這時數(shù)據(jù)庫中的值為:
parent child
id id parent_id
1 1 1
2 1 2
3 1 3
我們繼續(xù)操作以體現(xiàn)外鍵關(guān)聯(lián)表的作用
mysql> update parent set id=4 where id=1;#改變parent的值看一下child的反應
mysql> select * from parent;
mysql> select * from child;
這時數(shù)據(jù)庫中的值為:
parent child
id id parent_id
2 1 4
3 1 2
4 1 3
通過以上的例子大家可以清楚的看到用戶只是改變parent的值,而關(guān)聯(lián)的child值會自動改變。我們繼續(xù)
mysql> insert into child values(2,4),(3,4),(4,4);#為子表再添加一些其它的值。
mysql> #delete from parent where id=4; #大家執(zhí)行這條語句看一下有什么結(jié)果,錯誤吧?我們來分析一下提示錯誤
我們回顧一下我們創(chuàng)建外鍵的說細情況和關(guān)鍵語句:
foreign key(parent_id) #這句話的意思是指定對外關(guān)聯(lián)鍵為本表的parent_id;
references parent(id) on delete restrict on update cascade#這句話是則約束語句,references可以約束本數(shù)據(jù)庫的外鍵即parend_id與 parent數(shù)據(jù)表的id子鍵對應,并約束了on delete,on update時的操作,mysql共有以下幾種操作:
(1) restrict、no action 表示如果子表中有匹配的記錄,則不允許對父表對應候選鍵進行update/delete操作 ,大家現(xiàn)在明白了吧?為什么我們執(zhí)行delete from parent where id=4;時出現(xiàn)錯誤,因為子表(child)中還存在值.
(2) set null 在父表上update/delete記錄時,將子表上匹配記錄的列設為null,但要注意子表的外鍵列不能為not null
(3) cascade 在父表上update/delete記錄時,同步update/delete掉子表的匹配記錄
大家可以根據(jù)自己的需要設置不同的動作,例如,我們要在父表刪除時,自動刪除子表的關(guān)聯(lián)值,則我們需進行設置:
references parent(id) on delete cascade on update cascade,實驗之前我們須要知道
1.已經(jīng)定義設置好的外鍵是無法再行更改的,必須要刪除外鍵后再行創(chuàng)建(可能還有別的方法,哪位高手指點一下)
mysql> show create table child/G #得到 constraint(約束)的名字
說明:constraint是可以缺省的,用于指定約束的名字,如果不指定則系統(tǒng)會自動為它取名,例如我們可以這樣:
constraint fk_child_key
foreign key(parent_id)
references parent(id) on delete restrict on update cascade;
這樣我們就指定了這個約束的整體名稱為fk_child_key,以后可以對這個進行操作了.
mysql> alter table child drop foreign key fk_child_key;#刪除約束
mysql> alter table child add foreign key ('parent_id)
references parent(id) on delete cascade
on update cascade;
mysql> show create table child/G #至此約束已更改,用戶可以查看一下更改情況
mysql>delete from parent where id=4;#我們再執(zhí)行上面的那句,這時沒錯誤了吧?
mysql>select * from parent;
mysql>select * from child; #我們可以看到現(xiàn)在與parent_id為4的全部刪除。呵呵,以后都可以方便的使用了
這時數(shù)據(jù)庫中的值為:
parent child
id id parent_id
2 1 2
3 1 3
6.數(shù)據(jù)約束 的額外說明
如果定義了數(shù)據(jù)約束,則數(shù)據(jù)的插入或更改速度會很慢,特別是更改數(shù)據(jù)結(jié)構(gòu),插入數(shù)據(jù)時,效率低的可怕。
當客戶執(zhí)行l(wèi)oad data(載入數(shù)據(jù),后續(xù)會介紹),alter table時建議使用以下命令,暫時關(guān)閉數(shù)據(jù)約束,等完成后再開啟,這樣速度至少可以提升20倍以上。
mysql> set foreign_key_checks=0;#關(guān)閉數(shù)據(jù)約束
mysql> load data infile '文件絕對地址' into table 表名;#從文本文件中載入大量數(shù)據(jù)
mysql> set foreign_key_checks=1;#打開數(shù)據(jù)約束