表格中,删除一行:(表的操作,要删除只能以行为单位,不可能单独把某一行的某一列删除,如果某一行上的某一列不见了,这属于修改操作。)
数据库服务器------->N多库--------->N张表(行与列)--------->数据
1.先建立数据库服务器。
2.建立一个库。
3.再建表。
(所谓建表:就是声明列的过程),数据以文件形式放在硬盘(也放在内存里)
表中的四个基本操作:增、删、改、查。
(数据项是数据的最小单元,数据元素是数据的基本单元)
①增:insert into ②删:delete
③改:update ④查:select * from
增:往哪张表增,增那几列,各为什么值?
Insert into 表名
(列1,列2...)
values
(值1,值2...);
若不声明插入的列,泽默认插入所有列。
改:修改哪张表,修改那几列,修改成什么值?
Update 表名
Set
列1=值1,
列2=值2,
....
Where 表达式;
删:删除哪张表,删除那几行?
Delete from 表名
Where 表达式
查:Select * from 表名
Where 表达式
选列原则:够用又不浪费
数值型:
整型:Tinyint、Smallint、Mediumint、Int、Bigint
小数型/浮点型与定点型
Float(M,D)-->M:精度(总位数,不包含点);D:标度(小数位)
Decimal(M,D)更精确
从数学上讨论Tinyint
(1)占据空间 (2)存储范围
Tinyint:微小的列类型,占1个字节(8个位)默认是有符号的,储存-128->127.
(如果表示负数,可用最高位来标志符号位)
类型 |
字节 |
位 |
无符号 |
有符号 |
Tinyint |
1 |
8 |
0->255 |
-2^7->+2^7-1 |
Smallint |
2 |
16 |
0->2^16-1 |
-2^15->+2^15-1 |
Mediumint |
3 |
24 |
0->2^24-1 |
-2^23->+2^23-1 |
Int |
4 |
32 |
0->2^32-1 |
-2^31->+2^31-1 |
Bigint |
8 |
49 |
0->2^40-1 |
-2^39->+2^39-1 |
整型列的可选属性:Tinyint(M) unsigned zerofill
Tinyint(M):宽度(在0填充的时候才有意义)
Unsigned:无符号类型(非负)
Zerofill:0填充(默认无符号)
列可以声明默认值(推荐):Not null Default 0
字符型:char、Varchar、Text(M代表宽度,可容纳的字符数)
类型 |
说明 |
典型声明方式 |
范围 |
Char |
定长字符串 |
Gender char(1) |
Char(M) 0<=M<=255 |
Varchar |
变长字符串 |
Email varchar(20) |
Varchar(M) 0<=M<=65535 约2W-6W个字符,受字符集影响 |
Text |
文本串 |
Content text |
约2W-6W个字符,受字符集影响 |
区别:(在速度上定长较快)
定长:M个字符,若存的小于M个字符,实占M个字符,利用率<=100%。
若不够M个字符,使用空格补齐,取时将后面的空格去掉。
若内容最后有空格,将会被清除。
变长:M个字符,若存的小于M个字符,N<=M,实占N个+(1-2)字节,利用率N/(N+1--2)<100%。
选择原则:空间利用率、速度
Text:可存较大文本段,搜索速度稍慢(不加默认值,加了也没用)
日期/时间型:Date 日期、Time 时间、 Datetime 日期时间类型、 Year 年类型
Year类型:1个字节表示1901-2155,[0000表示错误时选择]
Date类型:
(1)典型格式:0000-00-00
(2)范围:‘1000-01-01’-->‘9999-12-31’
Time类型:
(1)典型格式:00:00:00
(2)范围:‘-838:59:59’-->‘+838:59:59’
Detetame类型:
(1)典型格式:0000-00-00 00:00:00
(2)范围:‘1000-01-01 00:00:00 ’-->‘9999-12-31 23:59:59’
注意:
在开发中,很少用日期时间类型来表示一个需要的精确到秒的时间.
原因:虽然日期时间类型能精确到秒,方便查看,但是计算不方便.一般使用时间戳来表示。
时间戳:用int来存储
是1970-01-01 00:00:00到当前的秒数.
一般存注册时间,商品发布时间不等,并不是用datetime存储,而是用时间戳。
用int型存储时间戳方便计算,对于显示来说也可以方便的格式化.
Where型子查询:把内层查询的结果作为外层查询的比较条件
查询最大/最贵商品
From型子查询:把内层查询的结果当成临时表,供外层sql再次查询
查询每个栏目下的最新/最贵商品
Exists型子查询:把外层的查询结果拿到内层,看内层的查询是否成立
查询有商品的栏目
Union;联合
作用:把两次货多次查询结果合并
要求:两次查询的列数一致
推荐:查询的每一列,对应的列类型也一样
可以来自多张表
多次sql语句取出的列名可以不一致,此时以第一个sql的列名为准.
如果不同的语句中取出的行,有完全相同的(每个列的值都相同),那么相同的行将会合并(重复)
如果不去重复,可以加all来指定
如果子句中有order by,limit时,需加(),推荐放到所有子句之后,即对最终合并后的结果来排序
在子句中,order by配合limit使用才有意义,如果order by 不配合limit使用,会被语法分析器优化分析时,去除
引入:
一张表就是一个集合,一行数据是一个集合的元素
理论上讲:不可能勋在完全相同的,但在表中可以存在完全相同的两行
因为表内部有一个rowid
左连接:left
Select 列1,列2,列N from
TableA left join tableB
On tableA 列 = tableB;【此处表连接成一张大表,完全当成普通表看】
后面可与5种子句联合使用
右连接:right
Select 列1,列2,列N from
TableA right join tableB
On tableA 列 = tableB;【此处表连接成一张大表,完全当成普通表看】
后面可与5种子句联合使用
内连接:inner
Select 列1,列2,列N from
TableA inner join tableB
On tableA 列 = tableB;【此处表连接成一张大表,完全当成普通表看】
后面可与5种子句联合使用
区别:
左右连接:以左表为准,去右表找匹配数据,找不到匹配,用NULL补齐
记忆:
替右连接,兼容性好一些)
(A left join B ==B right join A)
内连接:
查询左右表都有的数据,即:不要左右连接中NULL的那一部分
内连接是:左右连接的交集
思考:要查出左右连接的并集时,可用union来达到目的
Create table 表名(
列名称 列类型 [列属性] [默认值],------> 列声明
列名称 列类型 [列属性] [默认值],
列名称 列类型 [列属性] [默认值]
)charset =utf8/gbk/...
表增加列,修改列,删除列
增加列:Alter table 表名 add 列声明
增加的列默认是在表的最后一列
可以用after来声明新增的列在哪一些后面
例:alter table 表名 add 列声明 after flower
如果新增的列放在第一列
例:alter table 表名 add 列声明 first
修改列:Alter table 表名 change 被改变的列名
删除列:Alter table 表名 drop 列名;
定义:由查询结果形成的一张虚拟表
创建语法:Create view 视图名 as select 语句
删除语法:Drop view
为什么要视图?
1.简化查询
2.可以进行权限控制(把表的权限封闭,但是开放相应的视图权限,视图里只开放部分数据)
3.大数据分表时可以用到(将一张表的数据拆成N张表来存放)
例:把一张表的数据分散到4张表里
最常用可以用id取模来计算
Id%4+1=[1,2,3,4]
Eg:$_GET[‘id’]=17,
17%4+1=2,$tablename=’news’.’2’
Select * from news2 where id = 17;
还可以用视图,将4张表形成一张视图
Create view news as select from n1 union select from n2 union....
视图的修改:Alter view as select XXXXX
视图与表的关系:
视图是表的查询结果,表的数据改变,影响视图结果
若视图改变时:
视图增删改也会影响表,但是,视图并不是总能增删改
当视图的数据与表的数据一一对应时可以修改
对于视图insert还应注意
视图必须包含表中没有的默认值的列
视图的algorithm
Algorithm=merge/temptable/undefined
Merge:当引用视图时,引用视图的语句与定义视图的语句合并
(意味着视图只是一个语句规则,当查询视图时,把查询视图的语句与创建时的语句where子句等合并,分析形成一条select语句)
Temptable:当引用视图时,根据视图的创建语句建立一个临时表
(根据创建语句瞬间创建一张临时表,然后查询视图的语句从该临时表查数据)
Underfined:未定义,自动,让系统帮你选
字符集:
Create table表名(
列声明
)charset utf8
Mysql的字符集设置非常灵活,可以设置服务器字符集,数据库默认字符集,表默认字符集,列字符集,如果某一个级别没有指定字符集,则继承上一级
以表声明utf8为例:存储的数据在表中最终是utf8
1.告诉服务器,我给你发送的数据是什么编码?Character_set_client
2.告诉转换器转换成什么编码?Character_set_connection
3.查询的结果用什么编码?Character_set_results
如果以上3者都为字符集N,则可以简写为set names N
推论1:什么时候会乱码?
1.client声明与事实不符
2.Results与客户端页面不符时
推论2:什么时候数据会丢失?
Connection和服务器的字符集比client小时
校对集:指字符集的排序规则(可以有一个或多个)
以utf8为例,默认使用utf8_general_ci规则,也可以按二进制排,utf8_bin
怎样声明校对集:Create table()...charset utf8 collate utf8_general_ci;
注意:声明的校对集必须是字符集合法的校对集。
作用:监视某种情况并触发某种操作,能监视增、删、改
触发操作:增、删、改
观察以下场景:
一个电子商城,
商品表,g
主键 |
商品名 |
库存 |
1 |
电脑 |
28 |
2 |
自行车 |
12 |
订单表,o
订单主键 |
商品外键 |
购买数量 |
1 |
2 |
3 |
2 |
1 |
5 |
完成下单与减少库存的逻辑:
Insert into o(gid,num)values(2,3); //插入语句
Update g set goods_num=goods_num – 3 where id=2;//更新过程
这两个逻辑可以看成一个整体,或者说,insertà引来update
用触发器可以解决上诉问题:我们可以监视某表的变化,当发生某种变化时,触发某个操作
触发器创建语法四要素:
监视地点(table) 监视事件(insert/update/delete)
触发事件(after/betore) 触发事件(insert/update/delete)
创建触发器的语法:
create trigger triggername
after/before insert/update/delete on 表名
for each row //固定语句
begin
sql语句; //一句或多句(insert/update/delete范围内)
end$
删除触发器的语法:Drop trigger triggername
Eg:#监视地点:o表
#监视操作:insert
#触发操作:update
#触发时间:after
查看触发器:Show triggers
只触发一种情况:
Delimiter $
Create trigger tg1
After insert on o
For each row
Begin
Update g set num = num – 3 where id = 2;
End$
触发多种情况:
在触发器引用行的值
(对于insert而言,新增的行用new来表示,行中的每一列的值,用new . 列名来表示
对于delete而言,原本有一行,后来被删除,行中的每一列的值,用old . 列名表示
对于update而言,被修改的行
被修改前的数据,用old来表示,old.列名引用被修改之前行中的值
被修改后的数据,用new来表示,new.列名引用被修改之后行中的值)
Drop trigger tg1$
Create trigger tg2
After insert on o
For each row
Begin
Update g set num = num – new.much where id = new.gid;
End$
触发器中after与before的区别:
After先完成数据的增、删、改,
触发中的语句晚于增、删、改,无法影响前面的增、删、改动作
Before先完成触发,再增、删、改,
触发的语句先与监视的增、删、改发生,我们有机会判断,修改即将发生的操作
对于用户来说:同样一张表的数据,无论用什么引擎来存储,用户看到的数据是一样的,但是对于服务器来说,有区别。
常用的表的引擎:
Myisam:批量插入速度高,事务安全低,支持全文索引,锁表
InnoDB:批量插入速度低,事务安全高,(5.5版本)支持全文索引,锁行
通俗的说事务:指一组操作,要么都成功执行,要么都不执行——原子性
在所有的操作没有执行完毕之前,其他的话不能够看到中间改变的过程——隔离性
事务发生前后,数据的总额依然匹配——一致性
事务产生的影响不能够撤销——持久性
如果出了错误,事务也不允许撤销,只能通过“补偿事务”
关于事务的引擎:选用InnoDB/bdb
开启事务:start transaction
Commit(提交)
rollback(回滚)
注意:1>当一个事务提交或者回滚时事务结束
2>有些语句会造成事务的隐式提交
事务的基本原理:不用事务时直接作用于表
系统运行中:增量备份与整体备份
Eg:每周日整体备份一次,周一到周六备份当天
备份的工具:有第三方的收费备份工具,系统自带的备份工具(mysqldump)
Mysqldump可以导出库\表
Eg:到处mugua库下面的account表
Mysqldump –u用户名 –p密码 库名 表1 表2 表3 >地址/备份文件名称
导出的是建表语句及insert语句
Eg:如何导出一个库下的所有表?
Mysqldump –u用户名 –p密码 库名 >地址/备份文件名称
Eg:如何以库为单位导出?
Mysqldump –u用户名 –p密码 –B 库1 库2 库3 >地址/备份文件名称
Eg:如何导出所有库?
Mysqldump –u用户名 –p密码 –A >地址/备份文件名称
如果是以库为单位导出sql文件
1.登录到mysql命令行
对于库级的备份文件:Mysql > source备份文件地址
对于表级的备份文件:Mysql > us库名,Mysql > source备份文件地址
2.不登录到mysql命令行
针对库级的备份文件地址:Mysql –u用户名 –p密码 < 库级备份文件名称
针对表级的备份文件地址:Mysql –u用户名 –p密码 库名 < 表级备份文件名称
Eg:散列算法—>中-->005
—>国-->007
—>人-->020
—>民-->099
[001] [002] [003] [ ] ··· [ ] [100]
弊端:1.算出的散列值不连续
2.算出的散列值可能会有同一结果(碰撞性,最大区间 )
好处:加快了查询速度(select)
坏处:降低了增删改的速度(update、delete,insert),增大了表的文件大小(索引文件甚至比数据文件还大 )
使用原则:不过度索引
索引条件列(where后面最频繁的条件比较适宜索引)
索引散列值,过于集中的值不要索引
普通索引(index):仅是加快查询速度
唯一索引(unique):行上的值不能重复
主键索引(primary key):主键不能重复
主键索引与唯一索引的区别:
1.主键必唯一,但是唯一索引不一定是主键
2.一张表上只能有一个主键,但是可以用一个或多个唯一索引
全文索引(fulttext):
1.全文索引的用法:Match(全文索引名)against(’keyword’)
2.全文索引的停止词:不针对非常频繁的词做索引
3.在mysql默认情况下对于中文意义不大
原因:英文有空格,标点符号来拆成单词,进而对单词进行索引而对于中文,无空格来隔开单词,mysql无法识别每个中文词
查看一张表上的所有索引:Show index from 表名
建立索引:alter table 表名 add index/unique/fulltext [索引名](列名)
alter table 表名 add primary key(列名)//不加索引名,因为主键只有一个
删除索引:删除非主键索引:alter table 表名 drop index 索引名
删除主键:alter table 表名 drop primary key
案例:设有新闻表15列,10列上有索引,共500w行数据,如何快速导入?
1.把空表的索引全部删除
2.导入数据
3.数据导入完毕后,集中建索引
类似于函数,就是把一段代码封装起来,当腰执行这一代码时,可以通过用该存储过程来实现,在封装的语句体里面,可以用if/else,case,while等控制结构,可以进行sql编程。
查看现有的存储过程:show procedure status
删除存储过程:drop procedure存储过程的名字
调用存储过程:call存储过程名字();
在mysql中,存储过程和函数的区别:
1.名称不同
2.存储过程没有返回值
原文:https://www.cnblogs.com/AmazingYGY/p/10539008.html