mysql許可權和使用注意事項及mysql 資料型別詳解和innodb,myisam區別
mysql使用者許可權管理(Grant,Revoke)
MySQL可以為不同的使用者分配嚴格的、複雜的許可權。這些操作大多都可以用SQL
指令Grant(分配許可權)和Revoke(回收許可權)來實現。 Grant可以把指定的權
限分配給特定的使用者,如果這個使用者不存在,則會建立一個使用者。
Grant 常用格式:
grant 許可權1,許可權2,…許可權n on 資料庫名稱.表名稱 to 使用者名稱@使用者地址
identified by ‘連線口令’;
許可權1,許可權2,…許可權n代表
select,insert,update,delete,create,drop,index,alter,grant,references,reload,shut
down,process,file等14個許可權。
當權限1,許可權2,…許可權n被all privileges或者all代替,表示賦予使用者全部許可權。
當資料庫名稱.表名稱被*.*代替,表示賦予使用者操作伺服器上所有資料庫所有表
的許可權。
使用者地址可以是localhost,也可以是ip地址、機器名字、域名。也可以用’%'表示
從任何地址連線。
‘連線口令’不能為空,否則建立失敗。
比較重要的是priveleges(許可權)。
普通使用者的許可權許可權應用於描述
SELECT表,列允許使用者從表中選擇行(記錄)
INSERT表,列允許使用者在表中插入新行
UPDATE表,列允許使用者修改現存表裡行中的值
DELETE表允許使用者刪除現存表的行
INDEX表允許使用者建立和拖動特定表索引
ALTER表允許使用者改變現存表的結構。例如,可新增列、重新命名列或表、修改列
的資料型別
CREATE資料庫,表允許使用者建立新資料庫或表。如果在GRANT中指定了一個特
定的資料庫或表,他們只能夠建立該資料庫或表,即他們必須首先刪除(Drop)
它
DROP資料庫,表允許使用者拖動(刪除)資料庫或表
管理員許可權許可權描述
CREATE TEMPORARY TABLES允許管理員在CREATE TABLE語句中使用
TEMPORARY關鍵字
FILE允許將資料從檔案讀入表,或從表讀入檔案
LOCK TABLES允許使用LOCK TABLES語句
PROCESS允許管理員檢視屬於所有使用者的伺服器程序
RELOAD允許管理員重新載入授權表、清空授權、主機、日誌和表格
REPLICATION CLIENT允許在複製主機(Master)和從機(Slave)上使用SHOW
STATUS
REPLICATION SLAVE允許複製從伺服器連線到主伺服器
SHOW DATABASES允許使用SHOW DATABASES語句檢視所有的資料庫列表。沒
有這個許可權,使用者只能看到他們能夠看到的資料庫
SHUTDOWN允許管理員關閉MySQL伺服器
SUPER允許管理員關閉屬於任何使用者的執行緒
特別的許可權許可權描述
ALL(或ALL PREVILEGES)授予所有許可權
USAGE不授予許可權。這將建立一個使用者並允許他登入,但不允許其他操作,如
update/select 等
例項:
例如:
mysql>grant select,insert,update,delete on test.user to
mql@localhost
identified by ‘123456′;
給本地的使用者mql分配可對資料庫test的user表進行select,insert,update,delete操
作的許可權,並設定口令為123456。若mql使用者不存在,則將自動建立此使用者. 具體
的許可權控制在mysql.db表中可以檢視到.也可直接對這個表進行更新操作進行許可權
的修改.
mysql>grant all privileges on test.* to
mql@localhost identified by ‘123456′;
給本地使用者mql分配可對資料庫test所有表進行所有操作的許可權,並設定口令為
123456。
mysql>grant all privileges on *.* to
mql@localhost identified by ‘123456′;
給本地使用者mql分配可對所有資料庫的所有表進行所有操作的許可權,並設定口令
為123456。
mysql>grant all privileges on *.* to [email protected] identified by ‘123456′
;
給來自10.127.46.128的使用者mql2分配可對所有資料庫的所有表進行所有操作的
許可權,並設定口令為123456。
REVOKE
REVOKE和作用和GRANT相反,語法格式為:
REVOKE privileges ON 資料庫名[.表名] FROM user_name
例如:
建立使用者Bob,密碼為“bob”,但不給他任何許可權:
GRANT usage on * to Bob identified by ’bob’;
授予Bob在books資料庫中的查詢和插入許可權:
GRANT select, insert on books.* to Bob;
取消Bob在books資料庫中的所有許可權:
REVOKE all on books.* from Bob;
注:需要指出的是,REVOKE all...僅僅是回收使用者的許可權,並不刪除使用者。在
MySQL中,使用者資訊存放在mysql.User中。MySQL可以通過DROP USER來徹底刪
除一個使用者,其用法為:
DROP USER user_name;
例如,要刪除使用者Bob,可以用:
DROP USER Bob;
mysql許可權級別
MySQL 中的許可權分為五個級別,分別如下:
1、Global Level:
總結:
1.1 全域性許可權控制是針對整個mysql的,對所有資料庫下的所有表及欄位都有效
1.2 使用*.*指定適合範圍的Global
Global Level 的許可權控制又稱為全域性許可權控制,所有許可權資訊都儲存在ysql.user
表中。Global Level 的所有許可權都是針對整個mysqld 的,對所有的資料庫下的所
有表及所有欄位都有效。如果一個許可權是以Global Level 來授予的,則會覆蓋其
他所有級別的相同許可權設定。比如我們首先給abc 使用者授權可以UPDATE 指定數
據庫如test 的t 表,然後又在全域性級別REVOKE 掉了abc 使用者對所有資料庫的所
有表的UPDATE 許可權。則這時候的abc 使用者將不再擁有用對test.t 表的更新許可權
。要授予Global Level 的許可權,則只需要在執行GRANT 命令的時候,用“*.*”來
指定適用範圍是Global 的即可,當有多個許可權需要授予的時候,也並不需要多次
重複執行GRANT命令,只需要一次將所有需要的許可權名稱通過逗號(“,”)分隔
開即可,如下:
root@localhost : mysql 05:14:35> GRANT SELECT,UPDATE,DELETE,INSERT ON
*.* TO 'user'@'localhost';
Query OK, 0 rows affected (0.00 sec)
2、Database Level
總結:
Database Level在Global Level下Database Level 是在Global Level 之下,其他
三個Level 之上的許可權級別,其作用域即為所指定整個資料庫中的所有物件。與
Global Level 的許可權相比,Database Level 主要少了以下幾個許可權:CREATE
USER,FILE,PROCESS,RELOAD,REPLICATION CLIENT,REPLICATION
SLAVE,SHOW DATABASES,SHUTDOWN,SUPER 和USAGE 這幾個許可權,沒有
增加任何許可權。之前我們說過Global Level 的許可權會覆蓋底下其他四層的相同權
限,Database Level 也一樣,
雖然他自己可能會被Global Level 的許可權設定所覆蓋,但同時他也能覆蓋比他更
下層的Table,Column 和Routine 這三層的許可權。
如果要授予Database Level 的許可權,則可以有兩種實現方式:
2.1、在執行GRANT 命令的時候,通過“database.*”來限定許可權作用域為
database 整個資料庫,如下:
第二步,訪問dms資料庫的表
注:經過此操作後(grant alter on dms.* to
'mes'@'10.86.87.18),使用者mes能夠
訪問資料庫dms中的所有表。
2.2、先通過USE 命令選定需要授權的資料庫,然後通過“*”來限定作用域,這樣
授權的作用域實際上就是當前選定的整個資料庫。
root@localhost : mysql 06:14:05> USE dms;
Database changed
root@localhost : test 06:13:10> GRANT DROP ON * TO'user'@'localhost';
Query OK, 0 rows affected (0.00 sec)
3、Table Level
總結:
3.1 Table Level是在Database Level之下
3.2 通過grant select on dms.ATTACHMENTS to
'user'@'localhost' ;方式進行分
配許可權Database Level 之下就是Table Level 的許可權了,Table Level 的許可權可以
被Global Level 和Database Level 的許可權所覆蓋,同時也能覆蓋Column Level 和
Routine Level 的許可權。Table Level 的許可權作用範圍是授權語句中所指定資料庫
的指定表。如可以通過如下語句給test 資料庫的t1 表授權:
第一步,分權訪問表的許可權、檢視許可權
grant select on dms.ATTACHMENTS to
'user'@'localhost' ;
show grants for
'user'@'localhost' ;
第二步,測試訪問表許可權
注:由此可知,發現進行授權後(grant select on dms.ATTACHMENTS to
Table Level 的許可權由於其作用域僅限於某個特定的表,所以許可權種類也比較少
,僅有ALTER,CREATE,DELETE,DROP,INDEX,INSERT,SELECT UPDATE
這八種許可權
4、Column Level
總結:
1 Column Level在Table Level之下
2 Column Level許可權僅有INSERT、SELECT、UPDATE三種
Column Level 的許可權作用範圍就更小了,僅僅是某個表的指定的某個(活某些)
列。由於許可權的覆蓋原則,Column Level 的許可權同樣可以被Global,Database,
Table 這三個級別的許可權中的相同級別所覆蓋,而且由於Column Level 所針對的
許可權和Routine Level的許可權作用域沒有重合部分,所以不會有覆蓋與被覆蓋的關
系。針對Column Level 級別的許可權僅有INSERT,SELECT 和UPDATE 這三種。
Column Level 的許可權授權語句語法基本和Table Level 差不多,只是需要在許可權
名稱後面將需要授權的列名列表通過括號括起來,如下:
第一步,分配許可權、檢視許可權
mysql> grant select(BANDANAID,BANDANACONTEXT) on dms.BANDANA to
第二步,驗證使用者mes是否具有訪問表BANDANA列的許可權
注:經測試,發現使用者只有訪問表BANDANA分配的兩個列的許可權,並沒有訪問
其他列的許可權。
5、Routine Level(常規)
總結:
5.1 Routine Level主要只有EXECUTE 和ALTER ROUTINE兩種許可權
5.2 Routine Level 主要針對函式和儲存過程兩個物件
Routine Level 的許可權主要只有EXECUTE 和ALTER ROUTINE 兩種,主要針對的
物件是procedure 和function 這兩種物件,在授予Routine Level 許可權的時候,需
要指定資料庫和相關物件,如:
root@localhost : test 04:03:26> GRANT EXECUTE ON test.p1 to
Query OK, 0 rows affected (0.00 sec)
除了上面幾類許可權之外,還有一個非常特殊的許可權GRANT,擁有GRANT 許可權的
使用者可以將自身所擁有的任何許可權全部授予其他任何使用者,所以GRANT 許可權是
一個非常特殊也非常重要的許可權。GRANT 許可權的授予方式也和其他任何許可權都
不太一樣,通常都是通過在執行GRANT授權語句的時候在最後新增WITH GRANT
OPTION 子句達到授予GRANT 許可權的目的。
MySQL資料庫值得注意事項
使用MySQL,安全問題不能不注意。以下是MySQL提示的23個注意事項:
1. 如果客戶端和伺服器端的連線需要跨越並通過不可信任的網路,那麼就需要使
用SSH隧道來加密該連線的通訊。
2. 用setpassword語句來修改使用者的密碼,三個步驟,先“mysql-uroot”登陸資料
庫系統,然後“mysql>update mysql.user set password=password(newpwd)”,
最後執行“flush privileges”就可以了。
3. 需要提防的攻擊有,防偷聽. 篡改. 回放. 拒絕服務等,不涉及可用性和容錯方
面。對所有的連線. 查詢. 其他操作使用基於ACL即訪問控制列表的安全措施來完
成。也有一些對SSL連線的支援。
4. 除了root使用者外的其他任何使用者不允許訪問mysql主資料庫中的user表;
加密後存放在user表中的加密後的使用者密碼一旦洩露,其他人可以隨意用該使用者
名/密碼相應的資料庫;
5. 用grant和revoke語句來進行使用者訪問控制的工作;
6. 不使用明文密碼,而是使用md5()和sha1()等單向的哈系函式來設定密碼;
7. 不選用字典中的字來做密碼;
8. 採用防火牆來去掉50%的外部危險,讓資料庫系統躲在防火牆後面工作,或放
置在DMZ區域中;
9. 從因特網上用nmap來掃描3306埠,也可用telnetserver_host3306的方法測
試,不能允許從非信任網路中訪問資料庫伺服器的3306號TCP埠,因此需要在
防火牆或路由器上做設定;
10. 為了防止被惡意傳入非法引數,例如whereID=234,別人卻輸入
whereID=234OR1=1導致全部顯示,所以在web的表單中使用或來用字串,在
動態URL中加入%22代表雙引號. %23代表井號. %27代表單引號;傳遞未檢查過
的值給mysql資料庫是非常危險的;
11. 在傳遞資料給mysql時檢查一下大小;
12. 應用程式需要連線到資料庫應該使用一般的使用者帳號,只開放少數必要的權
限給該使用者;
13. 在各程式設計介面(CC++PHPPerlJavaJDBC等)中使用特定‘逃脫字元’函式;
在因特網上使用mysql資料庫時一定少用傳輸明文的資料,而用SSL和SSH的加密
方式資料來傳輸;
14. 學會使用tcpdump和strings工具來檢視傳輸資料的安全性,例如tcpdump-l-
ieth0-w-srcordstport3306|strings。以普通使用者來啟動mysql資料庫服務;
15. 不使用到表的聯結符號,選用的引數--skip-symbolic-links;
16. 確信在mysql目錄中只有啟動資料庫服務的使用者才可以對檔案有讀和寫的權
限;
17. 不許將process或super許可權付給非管理使用者,該mysql admin processlist可以
列舉出當前執行的查詢文字;super許可權可用於切斷客戶端連線. 改變伺服器執行
引數狀態. 控制拷貝複製資料庫的伺服器;
18. file許可權不付給管理員以外的使用者,防止出現loaddata/etc/passwd到表中再用
select顯示出來的問題;
19. 如果不相信DNS服務公司的服務,可以在主機名稱允許表中只設置IP數字地
址;
20. 使用max_user_connections變數來使mysqld服務程序,對一個指定帳戶限定
連線數;
21. grant語句也支援資源控制選項;
22. 啟動mysqld服務程序的安全選項開關,--local-infile=0或1若是0則客戶端程
序就無法使用local load data了,賦權的一個例子grant insert(user)on
mysql.user to user_name@host_name;若使用--skip-grant-tables系統將對任何
使用者的訪問不做任何訪問控制,但可以用mysql admin flush-privileges或
mysqladminreload來開啟訪問控制;預設情況是show databases語句對所有使用者
開放,可以用--skip-show-databases來關閉掉。
23. 碰到Error1045(28000)AccessDeniedforuserroot@localhost
(Usingpassword:NO)錯誤時,你需要重新設定密碼,具體方法是:先用--skip-
grant-tables引數啟動mysqld,然後執行mysql -root mysql,mysql>update user
set password=password(newpassword)where user=root;mysql>Flush
privileges;,最後重新啟動mysql就可以了。
Mysql 資料型別詳解
1) 整數型 tinyint int bigint
int(20) 和int (12) 有區別嗎?(括號裡面是長度)
MySQL支援選擇在該型別關鍵字後面的括號內指定整數值的顯示寬度(例如,INT(4))
。int(M) 在 integer 資料型別中,M 表示最大顯示寬度,該可選顯示寬度規定用於顯
示寬度小於指定的列寬度的值時從左側填滿寬度。
在 int(M) 中,M 的值跟 int(M) 所佔多少儲存空間並無任何關係。和數字位數也無關
系, int(3)、int(4)、int(8) 在磁碟上都是佔用 4 btyes(即32位) 的儲存空間。
例如,對於宣告為INT(5) ZEROFILL的列,值4檢索為00004。
int bigint smallint 和 tinyint 型別,如果建立新表時沒有指定 int(M) 中的M時,預設
分別是 :
int ------- int(11)
bigint ------- bigint(20)
smallint ------- smallint(6)
tinyint ------- tinyint(4)
型別 位元組 最小值 最大值 (無符號的取值範圍)
TINYINT 1 -128 127 0 255
SMALLINT 2 -32768 32767 0 65535
MEDIUMINT 3 -8388608 8388607 0 16777215
INT 4 -2147483648 2147483647 0 4294967295
BIGINT 8 -9223372036854775808 9223372036854775807 0
18446744073709551615
2) 數值型
decimal
DECIMAL和NUMERIC型別在MySQL中視為相同的型別。它們用於儲存必須為確切精
度的值,例如貨幣資料。當宣告該型別的列時,可以(並且通常要)指定精度和標度;
例如:salary DECIMAL(5,2)
在標準SQL中,語法DECIMAL(M)等價於DECIMAL(M,0)。同樣,語法DECIMAL等價於
DECIMAL(M,0),可以通過計算確定M的值。在MySQL 5.1中支援DECIMAL和
NUMERIC資料型別的變數形式。M預設值是10。
DECIMAL或NUMERIC的最大位數是65,但具體的DECIMAL或NUMERIC列的實際範圍
受具體列的精度或標度約束。如果此類列分配的值小數點後面的位數超過指定的標度
允許的範圍,值被轉換為該標度。(具體操作與作業系統有關,但一般結果均被擷取
到允許的位數)。
3) 字元型char varchar
char(2) 和varchar(2)有區別
當char欄位和varchar欄位使用索引的時候,他們有區別嗎
CHAR儲存定長資料很方便,CHAR欄位上的索引效率極高,比如定義char(10),那麼
不論你儲存的資料是否達 到了10個位元組,都要佔去10個位元組的空間。因為是固
定長度,所以速度效率高。比如定義char(10),那麼不論你儲存的資料是否達到了10
個位元組,都要佔去10個位元組的空間。因為是固定長度,所以速度效率高。
char varchar varchar2 的區別
區別:
1.CHAR的長度是固定的,而VARCHAR2的長度是可以變化的, 比如,儲存字串
“abc",對於CHAR (20),表示你儲存的字元將佔20個位元組(包括17個空字元),而同樣
的VARCHAR2 (20)則只佔用3個位元組的長度,20只是最大值,當你儲存的字元小於20
時,按實際長度儲存。
CHAR(1)與VARCHAR(1)兩這個定義,會有什麼區別呢?雖然這兩個都只能夠用
來儲存單個的字元,但是 VARCHAR要比CHAR多佔用一個儲存位置。這主要是因為使
用VARCHAR資料型別時,會多用1個位元組用來儲存長度資訊。這個管理上的開銷
CHAR 字元型別是沒有的。
2.CHAR的效率比VARCHAR2的效率稍高。
3.目前VARCHAR是VARCHAR2的同義詞。工業標準的VARCHAR型別可以儲存空字元
串,但是oracle不這樣做,儘管它保留以後這樣做的權利。Oracle自己開發了一個數
據型別VARCHAR2,這個型別不是一個標準的VARCHAR,它將在資料庫中varchar列
可以儲存空字串的特性改為儲存NULL值。如果你想有向後相容的能力,Oracle建
議使用VARCHAR2而不是VARCHAR。
支援多語言的站點應考慮使用 Unicode nchar 或 nvarchar 資料型別以儘量減少字元
轉換問題。否則使用 char 或 varchar:
如果希望列中的資料值大小接近一致,請使用 char。
如果希望列中的資料值大小顯著不同,請使用 varchar。
4) 文字型
tinytext
text
mediumtext
text最大的大小是多少?text欄位可以用索引嗎?
型別 範圍 說明
TinyText 最大長度255個字元(2^8-1)
Blob 最大長度65535個字元(2^16-1)
Text 最大長度65535個字元(2^16-1)
MediumBlob 最大長度 16777215 個字元(2^24-1)
MediumText 最大長度 16777215 個字元(2^24-1
LongBlob 最大長度4294967295個字元 (2^32-1)
LongText 最大長度4294967295個字元 (2^32-1)
Enum 集合最大數目為65535 列舉(Enumeration),Enum單選、sex enum(1,0)
Set 集合最大數目為64 Set複選 habby set(‘玩電玩’,'睡覺’,'看電影’,'聽音樂’)
PRIMARY, INDEX, UNIQUE 這3種是一類PRIMARY 主鍵。 就是 唯一 且 不能為空。
INDEX 索引,普通的UNIQUE 唯一索引。 不允許有重複。
FULLTEXT 是全文索引,用於在一篇文章中,檢索文字資訊的。
舉個例子來說,比如你在為某商場做一個會員卡的系統。
這個系統有一個會員表有下列欄位:
會員編號 INT會員姓名 VARCHAR(10)
會員身份證號碼 VARCHAR(18)
會員電話 VARCHAR(10)
會員住址 VARCHAR(50)
會員備註資訊 TEXT
那麼這個 會員編號,作為主鍵,使用 PRIMARY會員姓名
如果要建索引的話,那麼就是普通的 INDEX會員身份證號碼
如果要建索引的話,那麼可以選擇 UNIQUE (唯一的,不允許重複)
會員備註資訊 , 如果需要建索引的話,可以選擇 FULLTEXT,全文搜尋。
不過 FULLTEXT 用於搜尋很長一篇文章的時候,效果最好。用在比較短的文字,如
果就一兩行字的,普通的 INDEX 也可以。
在實際操作過程中,應該選取表中哪些欄位作為索引?
為了使索引的使用效率更高,在建立索引時,必須考慮在哪些欄位上建立索引和建立
什麼型別的索引,有7大原則:
1.選擇唯一性索引
2.為經常需要排序、分組和聯合操作的欄位建立索引
3.為常作為查詢條件的欄位建立索引
4.限制索引的數目
5.儘量使用資料量少的索引
6.儘量使用字首來索引
7.刪除不再使用或者很少使用的索引
5)時間型
datetime
timestamp
datetime跟 timestamp有區別嗎?
DATETIME、DATE 和 TIMESTAMP 型別是相似的。本篇描述了它們的特性以及它們
的相似點與不同點。
DATETIME 型別可用於需要同時包含日期和時間資訊的值。MySQL 以 'YYYY-MM-DD
HH:MM:SS' 格式檢索與顯示 DATETIME 型別。支援的範圍是 '1000-01-01 00:00:00'
到 '9999-12-31 23:59:59'。(“支援”的含義是,儘管更早的值可能工作,但不能保證
他們均可以。)
DATE 型別可用於需要一個日期值而不需要時間部分時。MySQL 以 'YYYY-MM-DD'
格式檢索與顯示 DATE 值。支援的範圍是 '1000-01-01' 到 '9999-12-31'。
TIMESTAMP 列型別提供了一種型別,通過它你可以以當前操作的日期和時間自動地
標記 Insert 或Update 操作。如果一張表中有多個 TIMESTAMP 列,只有第一個被自
動更新。
“完整”TIMESTAMP格式是14位,但TIMESTAMP列也可以用更短的顯示尺寸創造
最常見的顯示尺寸是6、8、12、和14。
你可以在建立表時指定一個任意的顯示尺寸,但是定義列長為0或比14大均會被強制
定義為列長14。
列長在從1~13範圍的奇數值尺寸均被強制為下一個更大的偶數。
列如:
定義欄位長度 強制欄位長度
TIMESTAMP(0) -> TIMESTAMP(14)
TIMESTAMP(15)-> TIMESTAMP(14)
TIMESTAMP(1) -> TIMESTAMP(2)
TIMESTAMP(5) -> TIMESTAMP(6)
所有的TIMESTAMP列都有同樣的儲存大小,
使用被指定的時期時間值的完整精度(14位)儲存合法的值不考慮顯示尺寸。
不合法的日期,將會被強制為0儲存
自動更新第一個 TIMESTAMP 列在下列任何條件下發生:
列值沒有明確地在一個 Insert 或 LOAD DATA INFILE 語句中被指定。
列值沒有明確地在一個 Update 語句中被指定,並且其它的一些列值已發生改變。(
注意,當一個 Update 設定一個列值為它原有值時,這將不會引起 TIMESTAMP 列的
更新,因為,如果你設定一個列值為它當前值時,MySQL 為了效率為忽略更新。)
明確地以 NULL 設定 TIMESTAMP 列。
第一個列以外其它 TIMESTAMP 列,可以設定到當前的日期和時間,只要將該列賦值
NULL 或 NOW()。
任何 TIMESTAMP 列均可以被設定一個不同於當前操作日期與時間的值,這通過為該
列明確指定一個你所期望的值來實現。這也適用於第一個 TIMESTAMP 列。這個選擇
性是很有用的,舉例來說,當你希望 TIMESTAMP 列儲存該記錄行被新新增時的當前
的日期和時間,但該值不再發生改變,無論以後是否對該記錄行進行過更新:
當該記錄行被建立時,讓 MySQL 設定該列值。這將初始化該列為當前日期和時間。
以後當你對該記錄行的其它列執行更新時,為 TIMESTAMP 列值明確地指定為它原來
的值。
另一方面,你可能發現更容易的方法,使用 DATETIME 列,當新建記錄行時以
NOW() 初始化該列,以後在對該記錄行進行更新時不再處理它。
6)列舉型
enum
enum(Y,N) 和 char(1)有區別嗎?
Enum 集合最大數目為65535 列舉(Enumeration),Enum單選、sex enum(1,0)
CHAR的長度是固定的,而VARCHAR2的長度是可以變化的, 比如,儲存字串“abc"
,對於CHAR (20),表示你儲存的字元將佔20個位元組(包括17個空字元),而同樣的
VARCHAR2 (20)則只佔用3個位元組的長度,20只是最大值,當你儲存的字元小於20時
,按實際長度儲存。
MySQL中engine=innodb和engine=myisam的區別
MyISAM型別不支援事務處理等高階處理,而InnoDB型別支援。 MyISAM型別的表強調的是效能,其執行數度比InnoDB型別更快,但是不提供事務支援,而InnoDB提供事務支援已經外部鍵等高階資料庫功能。這 樣就可以根據資料表不同的用處是用不同的儲存型別。
另外,MyISAM型別的二進位制資料檔案可以在不同作業系統中遷移。也就是可以直接從Windows系統拷貝到linux系統中使用。
修改:
ALTER TABLE tablename ENGINE = MyISAM ;
MyISAM:這個是預設型別,它是基於傳統的ISAM型別,ISAM是Indexed Sequential Access Method (有索引的 順序訪問方法) 的縮寫,它是儲存記錄和檔案的標準方法.與其他儲存引擎比較,MyISAM具有檢查和修復表格的大多數工具. MyISAM表格可以被壓縮,而且它們支援全文搜尋.它們不是事務安全的,而且也不支援外來鍵。如果事物回滾將造成不完全回滾,不具有原子性。如果執行大量 的SELECT,MyISAM是更好的選擇。
InnoDB:這種型別是事務安全的.它與BDB型別具有相同的特性,它們還支援外來鍵.InnoDB表格速度很快.具有比BDB還豐富的特性,因此如果需要一個事務安全的儲存引擎,建議使用它.如果你的資料執行大量的INSERT或UPDATE,出於效能方面的考慮,應該使用InnoDB表,
對於支援事物的InnoDB型別的標,影響速度的主要原因是AUTOCOMMIT預設設定是開啟的,而且程式沒有顯式呼叫BEGIN 開始事務,導致每插入一條都自動Commit,嚴重影響了速度。可以在執行sql前呼叫begin,多條sql形成一個事物(即使autocommit打 開也可以),將大大提高效能。
===============================================================
1. 4.0以上mysqld都支援事務,包括非max版本。3.23的需要max版本mysqld才能支援事務。
2. 建立表時如果不指定type則預設為myisam,不支援事務。
可以用 show create table tablename 命令看錶的型別。
2.1 對不支援事務的表做start/commit操作沒有任何效果,在執行commit前已經提交,測試:
執行一個msyql:
use test;
drop table if exists tn;
create table tn (a varchar(10)) type=myisam;
drop table if exists ty;
create table ty (a varchar(10)) type=innodb;
begin;
insert into tn values('a');
insert into ty values('a');
select * from tn;
select * from ty;
都能看到一條記錄
執行另一個mysql:
use test;
select * from tn;
select * from ty;
只有tn能看到一條記錄
然後在另一邊
commit;
才都能看到記錄。
3. 可以執行以下命令來切換非事務表到事務(資料不會丟失),innodb表比myisam表更安全:
alter table tablename type=innodb;
3.1 innodb表不能用repair table命令和myisamchk -r table_name
但可以用check table,以及mysqlcheck [OPTIONS] database [tables]
4. 啟動mysql資料庫的命令列中添加了以下引數可以使新發布的mysql資料表都預設為使用事務(
隻影響到create語句。)
--default-table-type=InnoDB
測試命令:
use test;
drop table if exists tn;
create table tn (a varchar(10));
show create table tn;
5. 臨時改變預設表型別可以用:
set table_type=InnoDB;
show variables like 'table_type';
或:
c:/mysql/bin/mysqld-max-nt --standalone --default-table-type=InnoDB
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type, not counting to TEXT or BLOBs。
MySQL建立表,出現錯誤:
ERROR 1118 (42000): Row size too large. The maximum row size for the used table type,
not counting BLOBs, is 65535. You have to change some columns to TEXT or BLOBs。
於是在網上搜索了好久結果發現mysql建表有個長度限制:MySQL要求一個行的定義長度不能
超過65535。
(1)單個欄位如果大於65535,則轉換為TEXT 。
(2)單行最大限制為65535,這裡不包括TEXT、BLOB。
所謂單行最大限制指的就是一張表中所有欄位的所設定的長度不得超過65535位元組,
例如一個表中有三個varchar欄位長度30000,那麼這個表的單行長度為:30000*3=90000,
大於65535則報錯不能建表,這裡乘以3是因為資料庫用的utf8編碼,3個位元組表示一個字元。
解決辦法:
找到原因後到回去檢視entity實體程式碼發現這個沒有建立的表中大概有一百多個欄位,而且很
多string型別的欄位沒設定欄位大小(沒設定大小的情況下,預設建立varchar 255 長度),
於是乎把所有沒必要設定成255長的的欄位都設定小一點,改好後執行專案建表成功。(如果
你的表的中的欄位長度不能改小,那就把大欄位型別改成text型別,因為單行最大限制為
65535,這裡不包括TEXT、BLOB。)