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 mql2@61.127.46.128 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 整个数据库,如下:
第一步,分配权限,查看权限
grant alter on dms.* to 'user'@'localhost';
mysql> show grants for 'user'@'localhost';
第二步,访问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
'user'@'localhost' ;),mes就有访问表ATTACHMENTS的权限。
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
mysql> show grants for 'user'@'localhost';
第二步,验证用户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。)