一:字段修饰符 mysql
1:null和not null修饰符 算法
咱们经过这个例子来看看 sql
mysql> create table worker(id int not null,name varchar(8) not null,pass varchar(20) not null); 数据库
mysql> insert into worker values(1,'HA','123456'); 安全
mysql> insert into worker values(1,'LB',null); 服务器
ERROR 1048 (23000): Column 'pass' cannot be null 不能为null 并发
mysql> insert into worker values(2,'HPC',''); 高并发
注:NOT NULL 的字段是不能插入“NULL”的,只能插入“空值”。 性能
咱们可能有这些疑问<null和not null区别> 测试
一、字段类型是not null,为何能够插入空值
二、为何not null的效率比null高
三、判断字段不为空的时候,到底要 select * from table where column <> '' 仍是要用 select * from table where column is not null 呢。
“空值” 和 “NULL”有什么不同?
一、空值是不占用空间的
二、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表明杯子中装满了空气,虽然杯子看起来都是空的,可是里面是有空气的。
对于问题2,为何not null的效率比null高?
NULL 其实并非空值,而是要占用空间,因此mysql在进行比较的时候,NULL 会参与字段比较,因此对效率有一部分影响。
并且索引时不会存储NULL值的,因此若是索引的字段能够为NULL,索引的效率会降低不少。
-Mysql难以优化引用可空列查询,它会使索引、索引统计和值更加复杂。可空列须要更多的存储空间,还须要mysql内部进行特殊处理。可空列被索引后,每条记录都须要一个额外的字节,还能致使MyISAM中固定大小的索引变成可变大小的索引--------这也是《高性能mysql第二版》介绍的解读:“可空列须要更多的存储空间”:须要一个额外字节做为判断是否为NULL的标志位“须要mysql内部进行特殊处理”
因此使用not null 比null效率高
对于问题3. 判断字段不为空的时候,到底要 select * from table where column <> '' 仍是要用 select * from table where column is not null咱们举例看看
mysql> create table test(col1 varchar(10) not null, col2 varchar(10) null)ENGINE=MyISAM;
mysql> insert into test values('',null);
mysql> insert into test values('1','2');
mysql> insert into test values('','1');
下面我分别用这两条语句查询看看
为空表示不占空间,null占用空间
2:default 设定字段的默认值
为字段指定默认的值
mysql> create table test2(name varchar(8) not null,dept varchar(25) default 'SOS');
mysql> insert into test2 (name) values ('kko');
总结 :
若是字段没有设定default ,mysql依据这个字段是null仍是not null,若是为能够为null,则为null。若是不能够为null,报错。。
若是时间字段,默认为当前时间 ,插入0时,默认为当前时间。
若是是enum 类型,默认为第一个元素。
3:auto_increment字段约束
自动增加
只能修饰 int字段。 代表mysql应该自动为该字段生成一个惟一没有用过的数(每次在最大ID值的基础上加1。特例:若是目前最大ID是34,而后删除34,新添加的会是35.)。对于主键,这是很是 有用的。 能够为每条记录建立一个唯一的标识符
mysql> create table items ( id int not null auto_increment primary key , label varchar(20) not null);
mysql> insert into items (label) values ('aaba');
mysql> insert into items values (9,'aaba');
再插入一条id将为多少
mysql> insert into items (label) values ('abc');
Id为10
mysql> insert into items values (9,'adl');
ERROR 1062 (23000): Duplicate entry '9' for key 'PRIMARY'
insert into items (label) values ('abcs'); IDmax =11 max=11
delete from items where label='abcs'; IDmax=10 max=11
insert into items (label) values ('abcsw'); Idmax=11 max=12
主键约束惟一
二:清除表中的记录
清空表中全部记录
方法一:delete 不加where条件,清空全部表记录。可是delete不会清零auto_increment 值
mysql> delete from items;
mysql> insert into items (label) values ("aaaa");
方法二:删除表中全部记录,清auto_increment 值。
truncate
做用: 删除表的全部记录,并清零auto_increment 值。新插入的记录从1开始。
语法: truncate table name;
mysql> truncate table items;
mysql> insert into items values(null,'abv');
mysql> insert into items(label)values('hkuyb');
三:索引
索引是一种特殊的文件(InnoDB数据表上的索引是表空间的一个组成部分),它们包含着对数据表里全部记录的引用指针。更通俗的说,数据库索引比如是一本书前面的目录,能加快数据库的查询速度。
优势:为了加快搜索速度,减小查询时间 。
缺点:
1 索引是以文件存储的。若是索引过多,占磁盘空间较大。并且他影响: insert ,update ,delete 执行时间。
2索引中数据必须与数据表数据同步:若是索引过多,当表中数据更新的时候后,索引也要同步更新,这就下降了效率。
索引的类型
一、普通索引
二、惟一性索引
三、主键索引(主索引)
四、复合索引
普通索引
最基本的索引,不具有惟一性,就是加快查询速度
建立普通索引:
方法一:建立表时添加索引
create table 表名(
列定义
index 索引名称 (字段)
index 索引名称 (字段));
注:可使用key,也可使用index 。index 索引名称 (字段) ,索引名称,能够加也能够不加,不加使用字段名做为索引名。。
mysql> create table demo( id int(4), name varchar(20), pwd varchar(20), index(pwd) );
注意:index和 key 是相同的
mysql> create table demo1( id int(4), name varchar(20), pwd varchar(20), key(pwd) );
mysql> create table demo2( id int(4), name varchar(20), pwd varchar(20), key index_pwd(pwd) ); #加上名称
方法二: 当表建立完成后,使用alter为表添加索引:
alter table 表名 add index 索引名称 (字段1,字段2.....);
查看索引
注:若是Key是MUL, 那么该列的值能够重复, 该列是一个非惟一索引的前导列(第一列)或者是一个惟一性索引的组成部分可是能够含有空值NULL。就是表示是一个普通索引。
咱们先删除索引
mysql> alter table demo drop key pwd; 注意此处的pwd指的是索引的名称,而不是表中pwd的那个字段
再用alter添加
mysql> alter table demo add key(pwd);
惟一索引
与普通索引基本相同,但有一个区别:索引列的全部值都只能出现一次,即必须惟一,用来约束内容,字段值只能出现一次。应该加惟一索引。惟一性容许有NULL值<容许为空>。
建立惟一索引:
方法一:建立表时加惟一索引
create table 表名(
列定义:
unique key 索引名 (字段);
)
注意:经常使用在值不能重复的字段上,好比说用户名,电话号码,身份证号。
mysql> create table demo3(id int(4) auto_increment primary key, uName varchar(20), uPwd varchar(20), unique index (uName));
方法二:修改表时加惟一索引
alter table 表名 add unique 索引名 (字段);
mysql> alter table demo3 drop key uName;
mysql> alter table demo3 add unique(uName);
主键索引
查询数据库,按主键查询是最快的,每一个表只能有一个主键列,能够有多个普通索引列。主键列要求列的全部内容必须惟一,而索引列不要求内容必须惟一,不容许为空
建立主键索引
方法一:建立表建立主键索引
mysql> create table demo4 (id int(4) not null auto_increment primary key,name varchar(4) not null );
mysql> create table demo5( id int(4) not null auto_increment, name varchar(20) default null,primary key(id));
mysql> show create table demo5;
show index from demo5 \G
方法二:建立表后添加<不推荐>
先删除测试
删除遇到这种状况是auto_increment的缘由
mysql> alter table demo5 change id id int(4) not null;
mysql> alter table demo5 drop primary key;
再添加
mysql> alter table demo5 change id id int(4) not null primary key auto_increment;
总结:主键索引,惟一性索引区别:主键索引不能有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));
mysql> insert into firewall values('10.96.52.46',22,'deny');
mysql> insert into firewall values('10.96.52.46',21,'allow');
mysql> insert into firewall values('10.96.52.46',21,'allow');
ERROR 1062 (23000): Duplicate entry '10.96.52.46-21' 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开始支持全文索引。没法正确支持中文。
全文索引只能用在 varchar text
建立全文索引:
方法一:建立表时建立
create table 表名(
列定义,
fulltext key 索引名 (字段);
)
方法二:修改表时添加
alter table 表名 add fulltext 索引名 (字段);
ALTER TABLE `books` ADD FULLTEXT 索引名 (`author` )
强烈注意:MySQL自带的全文索引只能用于数据库引擎为MyISAM的数据表,若是是其余数据引擎,则全文索引不会生效
MySQL自带的全文索引只能对英文进行全文检索,目前没法对中文进行全文检索。
通常交给第三方软件进行全文索引
http://sphinxsearch.com/
索引设计原则:
索引并不是越多越好
数据量不大不须要创建索引
列中的值变化很少不须要创建索引 row id
常常排序(order by)和分组(group by)的列须要创建索引
惟一性约束对应使用惟一性索引
四:外键约束
什么是外键约束:
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 外部表名 (关联的字段) type=innodb
注:建立成功,必须知足如下4个条件:
一、确保参照的表和字段存在。
二、组成外键的字段被索引。
三、必须使用type指定存储引擎为:innodb.
四、外键字段和关联字段,数据类型必须一致。
例子:咱们建立一个数据库,包含用户信息表和订单表
mysql> create database market;
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;
#建立时,若是表名是sql关键字,使用时,须要使用反引号``
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;
注:
1:on delete cascade on update cascade 添加级联删除和更新:
2: :确保参照的表user中id字段存在。 组成外键的字段u_id被索引。 必须使用type指定存储引擎为:innodb。
外键字段和关联字段,数据类型必须一致。
插入测试数据
mysql> insert into user(name,sex)values('HA',1),('LB',2),('HPC',1);
mysql> insert into `order` (u_id,username,money)values(1,'HA',234),(2,'LB',146),(3,'HPC',256);
测试级联删除:
mysql> delete from user where id=1; 删除user表中id为1的数据
再查看order表
测试级联更新:
更新前数据状态
mysql> update user set id=6 where id=2;
测试数据完整性
外键约束,order表受user表的约束
在order里面插入一条数据u_id为5用户,在user表里面根本没有,因此插入不进去
mysql> insert into user values(5,'Find',1);
mysql> insert into `order` (u_id,username,money)values(5,'Find',346);
方法二:经过alter table 建立外键和级联更新,级联删除
语法:
alter table 数据表名称 add
[constraint [约束名称] ] foreign key (外键字段,..) references 数据表(参照字段,...)
[on update cascade|set null|no action]
[on delete cascade|set null|no action]
)
mysql> create table order1(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))type=innodb;
mysql> alter table order1 add foreign key(u_id) references user(id) on delete cascade on update cascade,type=innodb;
mysql> alter table order1 add constraint `bk`foreign key(u_id) references user(id) on delete cascade on update cascade,type=innodb; 指定外键名称
必定要记得带上innodb
mysql> show create table order1;
删除外键:
语法
alter table 数据表名称 drop foreign key 约束(外键)名称
mysql> alter table order1 drop foreign key order1_ibfk_1;
mysql> show create table order1;
五:视图
什么是视图
视图就是一个存在于数据库中的虚拟表。
视图自己没有数据,只是经过执行相应的select语句完成得到相应的数据。
咱们在怎样的场景使用它,为何使用视图
若是某个查询结果出现的很是频繁,也就是,要常常拿这个查询结果来作子查询这种
视图可以简化用户的操做
视图机制用户能够将注意力集中在所关心的数据上。若是这些数据不是直接来自基本表,则能够经过定义视图,使数据库看起来结构简单、清晰,而且能够简化用户的数据查询操做
视图是用户能以不一样的角度看待一样的数据。
对于固定的一些基本表,咱们能够给不一样的用户创建不一样的视图,这样不一样的用户就能够看到本身须要的信息了。
视图对重构数据库提供了必定程度的逻辑性。
好比原来的A表被分割成了B表和C表,咱们仍然能够在B表和C表的基础上构建一个视图A,而使用该数据表的程序能够不变。
视图可以对机密数据提供安全保护
好比说,每门课的成绩都构成了一个基本表,可是对于每一个同窗只能够查看本身这门课的成绩,所以能够为每一个同窗创建一个视图,隐藏其余同窗的数据,只显示该同窗本身的
适当的利用视图能够更加清晰的表达查询数据。
有时用现有的视图进行查询能够极大的减少查询语句的复杂程度。
建立视图
语法:create view视图名称(即虚拟的表名) as 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;