1. 程式人生 > >MySQL之庫、表操作

MySQL之庫、表操作

一、庫操作

建立庫
create database 庫名(charset utf8 對庫的編碼進行設定,不寫就用預設值)
庫名可以由字母、數字、下劃線、特殊字元,要區分大小寫,唯一性,不能使用關鍵字,不能用數字開頭,最長128位
檢視資料庫
注意:在cmd中輸入指令是不區分大小寫的 show databases;
#這檢視的是所有的庫 show create database db1; #這是檢視指定的庫 select database(); #這是檢視當前的庫 選擇資料庫 USE 資料庫名 #相當於在電腦上雙擊資料夾,進入資料夾 刪除資料庫 DROP DATABASE 資料庫名; 修改資料庫 alter database db1 charset utf8;
#只能修改庫的編碼格式

二、表操作

  1,儲存引擎

  儲存引擎就是表的型別,MySQL中根據不同的儲存引擎會有不同的處理機制,儲存引擎的概念是MySQL裡面才有的。

  1.1,MySQL的一個整個工作流程

  1.2,儲存引擎的分類

  在cmd中輸入show engines可以檢視所有的引擎,輸入show variables like 'storage_engine%'可以檢視當前使用的引擎。

  MyISAM引擎:

MyISAM引擎特點:
        1.不支援事務
            事務是指邏輯上的一組操作,組成這組操作的各個單元,要麼全成功要麼全失敗。
        
2.表級鎖定 資料更新時鎖定整個表:其鎖定機制是表級鎖定,也就是對錶中的一個數據進行操作都會將這個表鎖定,其他人不能操作這個表,這雖然可以讓鎖定的實現成本很小但是也同時大大降低了其併發效能。 3.讀寫互相阻塞 不僅會在寫入的時候阻塞讀取,MyISAM還會再讀取的時候阻塞寫入,但讀本身並不會阻塞另外的讀。 4.只會快取索引 MyISAM可以通過key_buffer_size的值來提高快取索引,以大大提高訪問效能減少磁碟IO,但是這個快取區只會快取索引,而不會快取資料。 5.讀取速度較快 佔用資源相對較少
6.不支援外來鍵約束,但只是全文索引 7.MyISAM引擎是MySQL5.5版本之前的預設引擎,是對最初的ISAM引擎優化的產物。
單一對資料庫的操作可以使用MyISAM,就是儘量純度、純寫

  InnoDB引擎:

InnoDB引擎
        介紹:InnoDB引擎是MySQL資料庫的另一個重要的儲存引擎,正稱為目前MySQL AB所發行新版的標準,被包含在所有二進位制安裝包裡。和其他的儲存引擎相比,InnoDB引擎的優點是支援相容ACID的事務(類似於PostGreSQL),以及引數完整性(即對外來鍵的支援)。Oracle公司與2005年10月收購了Innobase。Innobase採用雙認證授權。它使用GNU發行,也允許其他想將InnoDB結合到商業軟體的團體獲得授權。
InnoDB引擎特點:
        1.支援事務:支援4個事務隔離界別,支援多版本讀。
        2.行級鎖定(更新時一般是鎖定當前行):通過索引實現,全表掃描仍然會是表鎖,注意間隙鎖的影響。
        3.讀寫阻塞與事務隔離級別相關(有多個級別,這就不介紹啦~)。
        4.具體非常高效的快取特性:能快取索引,也能快取資料。
        5.整個表和主鍵與Cluster方式儲存,組成一顆平衡樹。(瞭解)
        6.所有SecondaryIndex都會儲存主鍵資訊。(瞭解)
        7.支援分割槽,表空間,類似oracle資料庫。
        8.支援外來鍵約束,不支援全文索引(5.5之前),以後的都支援了。
        9.和MyISAM引擎比較,InnoDB對硬體資源要求還是比較高的。
        小結:三個重要功能:Supports transactions,row-level locking,and foreign keys

  Memory引擎:把資料放在記憶體中

  BLACKHOLE引擎:黑洞引擎,資料放進去就消失

  1.3,儲存引擎的使用

  create table 表名(id int)engine=InnoDB  在建立表的時候可以指定引擎

  2,建立表

#語法:
create table 表名(欄位名1 型別[(寬度) 約束條件],欄位名2 型別[(寬度) 約束條件],欄位名3 型別[(寬度) 約束條件]);
#注意:
1. 在同一張表中,欄位名是不能相同
2. 寬度和約束條件可選、非必須,寬度指的就是欄位長度約束,例如:char(10)裡面的10
3. 欄位名和型別是必須的
show tables; #這是檢視當前庫下的所有表
describe 表名; #也可以寫成desc 表名,這是查看錶的結構
insert into 表名 values(填對應的資料); #這是向表裡面插入資料
select 表名(欄位)from 表名; #這是查看錶中某欄位的所有資料
select * from 表名; #這是查看錶中所有欄位的所有資料

  3,MySQL的基礎資料型別

  3.1,整數型別:tinyint,smallint,mediumint,int,bigint

tinyint[(m)] [unsigned] [zerofill]     
            小整數,資料型別用於儲存一些範圍的整數數值範圍:2**8
            有符號:-128 ~ 127
            無符號:0~ 255
            PS: MySQL中無布林值,使用tinyint(1)構造。
int[(m)][unsigned][zerofill]
            整數,資料型別用於儲存一些範圍的整數數值範圍:2**32
            有符號:-2147483648 ~ 2147483647
            無符號:0~ 4294967295
bigint[(m)][unsigned][zerofill]
            大整數,資料型別用於儲存一些範圍的整數數值範圍:  2**64
            有符號: -9223372036854775808 ~ 9223372036854775807
            無符號:0 ~  18446744073709551615
注意:對於整型來說,資料型別後面的寬度並不是儲存長度限度,而是顯示長度限制

  3.2,浮點型:

1.FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
    定義:單精度浮點數(非準確小數值),m是整數部分總個數,d是小數點後個數。m最大值為255,d最大值為30,例如:float(255,30]
    有符號: -3.402823466E+38 to -1.175494351E-38,
            1.175494351E-38 to 3.402823466E+38
    無符號: 1.175494351E-38 to 3.402823466E+38
    精確度: **** 隨著小數的增多,精度變得不準確 ****
2.DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
    定義:雙精度浮點數(非準確小數值),m是整數部分總個數,d是小數點後個數。m最大值也為255,d最大值也為30
    有符號: -1.7976931348623157E+308 to -2.2250738585072014E-308
            2.2250738585072014E-308 to 1.7976931348623157E+308
    無符號: 2.2250738585072014E-308 to 1.7976931348623157E+308          
    精確度:****隨著小數的增多,精度比float要高,但也會變得不準確 ***
3.decimal[(m[,d])] [unsigned] [zerofill]
    定義:準確的小數值,m是整數部分總個數(負號不算),d是小數點後個數。 m最大值為65,d最大值為30。比float和double的整數個數少,但是小數位數都是30位
    精確度:**** 隨著小數的增多,精度始終準確 ****
    對於精確數值計算時需要用此型別,decimal能夠儲存精確值的原因在於其內部按照字串儲存。
精度從高到低:decimal、double、float
decimal精度高,但是整數位數少,float和double精度低,但是整數位數多,float已經滿足絕大多數的場景了,但是什麼導彈、航線等要求精度非常高,所以還是需要按照業務場景自行選擇,如果又要精度高又要整數位數多,那麼你可以直接用字串來存。
在使用時,m必須大於d,不然會報錯

  3.3,日期型別:date,time,datetime,timestamp,year

year:YYYY(範圍:1901/2155)2018
date:YYYY-MM-DD(範圍:1000-01-01/9999-12-31)例:2018-01-01 
time:HH:MM:SS(範圍:'-838:59:59'/'838:59:59')例:12:09:32
datetime:YYYY-MM-DD HH:MM:SS(範圍:1000-01-01 00:00:00/9999-12-31 23:59:59    Y)例: 2018-01-01 12:09:32
timestamp:YYYYMMDD HHMMSS(範圍:1970-01-01 00:00:00/2037 年某時)

常用寫法:
create table t1(x datetime not null default now()); # 需要指定傳入,空值時預設取當前時間
create table t2(x timestamp); # 無需任何設定,在傳空值的情況下自動傳入當前時間

  3.4,字串型別

CHAR 和 VARCHAR 是最常使用的兩種字串型別。
CHAR(N)用來儲存固定長度的字串,對於 CHAR 型別,N 的範圍 為 0 ~ 255
VARCHAR(N)用來儲存變長字元型別,對於 VARCHAR 型別,N 的範圍為 0 ~ 65 535
CHAR(N)和 VARCHAR(N) 中的 N 都代表字元長度,而非位元組長度。#CHAR型別
對於 CHAR 型別的字串,MySQL 資料庫會自動對儲存列的右邊進行填充(Right Padded)操作,直到字串達到指定的長度 N。而在讀取該列時,MySQL 資料庫會自動將填充的字元刪除。我們可以把sql——mode設定為 PAD_CHAR_TO_ FULL_LENGTH,就會顯示填充的字元。#VARCHAR型別
VARCHAR 型別儲存變長欄位的字元型別,與 CHAR 型別不同的是,其儲存時需要在字首長度列表加上實際儲存的字元,該字元佔用 1 ~ 2 位元組的空間。當儲存的字串長度小 於 255 位元組時,其需要 1 位元組的空間,當大於 255 位元組時,需要 2 位元組的空間。
length(欄位) #檢視該欄位資料的位元組長度
char——length(欄位) #檢視該欄位資料的字元長度

  3.5,列舉型別enum和集合型別set

enum:單選,只能在給定的範圍內選一個值
set:多選,可以在給定的範圍內選擇一個或多個值
 示例:
  列舉
    CREATE TABLE shirts (name VARCHAR(
40),size ENUM('xsmall', 'small', 'medium', 'large', 'x-large')); INSERT INTO shirts VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
集合 CREATE TABLE myset (col SET('a', 'b', 'c', 'd')); INSERT INTO myset VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');

  4,表的完整性約束

  4.1分類

PRIMARY KEY (PK)    標識該欄位為該表的主鍵,可以唯一的標識記錄
FOREIGN KEY (FK)    標識該欄位為該表的外來鍵
NOT NULL    標識該欄位不能為空,不設定預設可以為空的
UNIQUE KEY (UK)    標識該欄位的值是唯一的
AUTO_INCREMENT    標識該欄位的值自動增長(整數型別,而且為主鍵)
DEFAULT    為該欄位設定預設值,不設定預設為null
UNSIGNED 無符號,不設定預設為有符號的
ZEROFILL 使用0填充

  4.2not null,default,unique,primary key,unsigned

create table t1(id int unsigned not null default 1) #表示id欄位為無符號,不可以為空,預設值為1
create table t1(id int unique) #表示id欄位的值不能重複
create table t1(id int ,name char(10),constraint ak_name unique(name)) #這也表示name不能重複
聯合唯一:
create table t1(id int,name char(10),unique(id,name)) #表示必須不能出現id和name都相同
主鍵:相當於not null + unique
create table t1(id int primary key)
create table t1(id int,name char(10),constriaint pk_name primary key(id) #這是兩種方式都可以設定主鍵,
聯合主鍵:
create table t1(id int,name char(10),primary key(id,name))

  4.3自動增長

create table t1(id int primary key auto_increment,name char(10)
insert into t1(name) values('nnn'),('sss'); #此時沒有輸入id,但id會從1開始自動增長
insert into t1 values(4,'rrr'); #當我們指定id了,就以指定的為準
insert into t1(name) values('tt') #現在的id也是自動增長,但是接著上一條的id開始增長
上面插入資料的id分別是:1,2,4,5
對於自動增長的欄位,可以用delete刪除資料,但再插入值時是按照刪除前最後一條資料的id值開始增長
delete from t1
select * from t1; #現在為空的
insert into t1(name)values('rtsa') #由於刪除前最後一條id為5,所以接上,那這一條id為6
用truncate清空表,在插入資料又是從1開始自增
truncate t1;
insert into t1(name) values('fsdf') #此時的id為1
在建立表的時候可以設定自動增長的起始值
create table t1(id int auto_increment,name char(10),auto_increment=3); #這樣設定後,表的自動增長就從3開始
建立表以後,也可以修改自增起始值
alter table t1 auto_increment=4;
設定步長
set session auto_increment_increment=2; #這是設定會話級別的步長
set global auto_increment_increment=2; #這是設定全域性級別的步長
例子:
set global auto_increment_increment=5;
set global auto_increment_offset=3;
最後得到的自動增長值為:1,6,11,16.。。。。。

  4.4外來鍵foreign key:其實就是表明表與表之間的關係,表與表之間有三種關係,一對一,一對多,多對多,在任何情況下都得先把‘一’的表(就相當於被指向的表)建立。

  一對多關係

先建立‘一’的表,就是dep表
create table dep(id int primary key,name char(10),comment char(10)); #然後插入資料就行
在建立‘多’的表,就是emp表,在emp表中的dep_id,指向的是dep表中的id
create table emp(id int primary key,name char(10),gender enum('male','female'),dep_id int,foreign key(dep_id) references dep(id) on delete cascade on update cascade);

  一對一關係:就只要把外來鍵設為唯一的就行了

先建立被指向的表,即customer表
create table customer(id int primary key,name char(10),phone int,qq int);
在建立student表,表中的cm_id指向customer表中的id
create table student(id int primary key,cname char(10),class_name,cm_id int unique,foreign key(cm_id) references customer(id) on delete cascade on update cascade);

  多對多關係:我們就應該建立第三個表(關聯表)來連線連個表的關係

多對多關係表,就應該最後建立關聯表就行,先建立另外兩個表就行,即author表和book表
create table author(id int primary key,name char(10));
create table book(id int primary key,bname char(10),price int);
最後來建立關聯表,即author表
create table author_book(id int primary key,author_id int,book_id int,foreign key(author_id) references author(id) on delete cascade on update cascade,
foreign key(book_id) references book(id) on delete cascade on update cascade);

注意:我們一般在建立表的時候最好把id設定為主鍵,其次是我們外來鍵指向的欄位必須是not null + unique的,最後是,在外來鍵的後面加上on delete cascade on update cascade,作用在於外來鍵的值會跟隨指向的欄位的值改變而改變

  5,表的修改alter table

語法:
1. 修改表名
      ALTER TABLE 表名 RENAME 新表名
2. 增加欄位
      ALTER TABLE 表名
                          ADD 欄位名  資料型別 [完整性約束條件…], #注意這裡可以通過逗號來分割,一下新增多個約束條件
                          ADD 欄位名  資料型別 [完整性約束條件…];
      ALTER TABLE 表名 ADD 欄位名  資料型別 [完整性約束條件…]  FIRST; #新增這個欄位的時候,把它放到第一個欄位位置去。
      ALTER TABLE 表名 ADD 欄位名  資料型別 [完整性約束條件…]  AFTER 欄位名;#after是放到後的這個欄位的後面去了,我們通過一個first和一個after就可以將新新增的欄位放到表的任意欄位位置了。                     
3. 刪除欄位
      ALTER TABLE 表名 DROP 欄位名;
4. 修改欄位
      ALTER TABLE 表名 MODIFY  欄位名 資料型別 [完整性約束條件…];#modify給欄位重新定義型別和約束條件,但已經有主鍵是不能修改,也不需要再寫
      ALTER TABLE 表名 CHANGE 舊欄位名 新欄位名 舊資料型別 [完整性約束條件…];  #change比modify還多了個改名字的功能,這一句是隻改了一個欄位名
      ALTER TABLE 表名 CHANGE 舊欄位名 新欄位名 新資料型別 [完整性約束條件…];#這一句除了改了欄位名,還改了資料型別、完整性約束等等的內容
5.增加複合主鍵
    alter table 表名 add primary key(欄位,欄位)
6.刪除主鍵
    alter table 表名 drop primary key #主鍵只能通過這方式進行刪除

  6,複製表

方法一
alter table t2 select * from t1; #複製結構+資料
這種情況下可以指定複製表的某些欄位,只需把*換成表名(欄位)就行,但是不能複製主鍵、外來鍵、自動增長約束條件
alter table t2 select * from t1 where 1=0; #因為1=0為假的,所以找不到對應資料,就只複製結構
方法二
create table t2 like t1;
這種方法只複製結構,沒有資料,但所有的約束條件都複製了