Mysql入门及重要规则

一.基本语法

  1. Insert Into table_name
    Values
    (’field1’,’field2’…)
  2. Insert Into table_name
    (field_name1,field_name2…)
    Values
    (’field1’,’field2’…)


Update table_name
Set
field_name = ‘field
Where exp


Delete From table_name
Where exp

  1. Select * From table_name Where exp
  2. Select field_name1,field_name2 From table_name Where exp

修改表
Alter Table table_name add field_name field_type field_args 增加列在表的最后

Alter Table … After field_name 指定列(first->第一列)

Alter Table table_name drop field_name 删除列

Alter Table table_name modify … 修改列

Alter Table table_name change field_name new_field_name修改列名

如果修改列属性值与原有数据不匹配,在mysql的严格匹配下,strick mod下修改不了

二.基本数据类型

  1. 数值型

     1)整型:TinyInt/SmallInt/MediumInt/Int/BitInt
    
类型字节数表示范围(有符号)
TinyInt1-128-127
SmallInt2从 -2^15 (-32,768) 到 2^15 - 1 (32,767)
MediumInt3从 -2^15 (-32,768) 到 2^15 - 1 (32,767)
Int4从 -2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647)
BigInt8从 -2^63 (-9223372036854775808) 到 2^63-1 (9223372036854775807)

unsigned:不加 默认是有符号的

zerofill:用0填充,自动unsigned

M:表示补0的宽度

零填充会自动使用无符号位
零填充指的是位数固定,如果数值长度不足字段类型的长度,则使用0来填充

2)浮点型:Float(M,D)

M:精度,代表小数点右边的总位数
D:标度,代表小数的总位数

float能存10^38,如果M<4,则占4个字节,否则装8个字节
还有一种浮点数是Decimal。是把整数部分和小数部分分开存储,比float更加精确。
float有时会丢失精度
Decimal把整数部分和小数部分的字节数加起来。

  1. 字符串

     1)char定长字符串
    

    定长能快速找到数据(寻址),无论够不够,都按这个长度存,如果长度不够,用空格在末尾补齐,浪费了尾部,这意味着如果右侧有空格,则会丢失。

     2)varchar变长字符串
    

    不用空格补齐,但列内容前有一两个字节来标志该列的内容长度,利用率小于100%

     3)text类型
    

    可以存比较大的文本,搜索速度较慢,不用加default,加了也没用。

     4)blob类型
    

    是二进制类型,用来存储图像,音频等信息。

  2. 日期类型

     1)date日期
    

    YYYY-MM-DD 3个字节
    0000-00-00 ~ 9999-12-31

     2)time时间 
    

    HH:MM:ss 3个字节
    -838:59:59 ~838:59:59

     3)datetime日期时间
    

    YYYY-MM-DD HH:MM:ss 8个字节
    1000-01-01 00:00:00~9999-12-31 23:59:59
    datestamp和datetime表示的信息相同,但范围不同,4个字节其默认值是current-time

     4)year年份类型
    

    YYYY和YY 不推荐 1个字节 0000是其默认错误的值

三.查询

  1. Where 条件查询,把列看作变量,变量之间可以运算
    1)In (’a’,’b’…)
    2)Between ‘a’ And ‘b
    3)Like% 匹配任意字符 _匹配单一字符
    4)Where里不能有未知字段

  2. Group与统计函数
    1)max/min/sum/avg/count
    其中count(?)表示列中该值不为null的总和,对比count(*)的写法,在myisam引擎的表结构中,没有区别,这种引擎内部有一计数器维护着行数,innodb的表,用count(*)读行,效率很低。
    分组再统计才能体现统计的意义
    如果select多个字段,若不加GroupBy,则会报错

  3. Having筛选
    Where只能选取表中已有的数据
    Having可以指定别名和表达式对结果集进行筛选

  4. OrderBy排序
    必须放在Where/Group By/Having 之后
    多字段排序:
    … Order By field_name ASC , field_name DESC

  5. Limit限制条目
    Limit 0,3 --> limit offset,num
    当group时,mysql是取每个分组下第一次出现的行,group by一定是要在 order by 之前。

  6. 子查询

    1)Where子查询
    Select field1,field2... From table_name Where field_name = (Select ...)

    如果返回的不是一列,就要用别名,必须是单行单列。
    Select field1,field2,field3... From table_name where a in (Select ...)

    内层sql只能返回单列,可以是多行。

    2)From子查询
    查询内层sql结果当成临时表

    3)Exists子查询
    指外层sql的结果拿到内层sql去测试

    Select field1,field2... From table_name Where Exists (Select ...)

四.连接查询

  1. Null
    Select * From table_name where filed_name != NULL
    是查不出来不为空的数据的,
    NULL = NULL 永远为假 NULL != NULL也为假
    Null的比较需要有特殊的运算符,Is Null 和 Is Not Null

  2. 连接查询
    一张表就是一个集合,每一行就是一个元素

    1)Select * From table_name1,table_name 两表全相乘
    2)tabl1 left join table2 on table1.field = tabla2.field 左连接

左连接不一定表示左表一定在左边。而是查询时以左边的表中数据为准

左右连接的区别
1.左右连接是可以互换的(所以尽量用左连接),
a left join b = b right join a

2.以那张表为准建立集合
3)table1 inner join table2 内连接,从集合的角度上来说,内连接就是取交集。

Union合并结果集,完成外连接的效果,不区分表

1)如果两表集合(列名)不一致,以第一个表的列名为准
2)但一定要字段的结构一样(数量和类型)
3)对有union的字段,内部排序被忽略(但是和limit结合有意义)在执行期间,被mysql代码分析器给优化掉了。
4)union会默认去重,如果不想去重加上union all

典型的两表统计计数:
Select sum(*) From (Select * From table1 Union all Select * From table2) Group By field_name

典型的篮球比分:
SELECT game_id,score,t1.team_name,t2.team_name FROM (game LEFT JOIN team as t1 ON t1.team_id = game.host_id) LEFT JOIN team as t2 ON t2.team_id = game.cost_id

五.视图

语法:Create View viewNane As Select ...
多一张动态表,但是是常驻内存和表一样查询。
用处:
1.简化查询
2.更精确的权限控制
3.分表查询

视图的修改问题
1.视图某些情况下是可以修改的,在字段中一一对应时,建立唯一的映射。
2.对于简单的视图,在发挥作用过程中并未建立临时的表,只是把查询条件保存下来。
使用关键字algorithm = merger/temptable/undefined指定视图的创建方式
create algorithm = merge View viewName As Select ...

六.编码问题

Ascii一个字节,只能保存英文和一些简单字符。

GB2312字符集2个字节,因为单字节小于127的值正好是ascii的值,那么gb2312就无法识别英文了,所以gb2312完全不占用0-127,但是因此中文组合也就少了,只能容纳6000多字。

GBK还是双字节,第二地位不再局限与129-155了,碰到128的。就往后再寻找一位
(140 35) 65 (179 82)
大致可以存2万多个汉字,九百多字符

ANSI代表本地字符集,在中文的操作系统上就是gbk

兼容各国:Unicode,是一个世界通用的码表,用4个字节来编号,有40多亿个子和,常用的集中在前65535个字符里,但是unicode只负责编号。

把高位浪费的0位,用一定规则舍弃掉,因此引进了Unicode Transform Format也就是
UTF变长编码,它将基本7位的ascii字符仍然用7位编码表示,而遇到与其它unicode字符混合的情况,将按照一定算法转换,每个字符用1-3个字节编码

所以uf8占几个字节?它是变长,所以如何确定字符的边界
用前缀
0开头一个字节 0xxxxxxx
110开头两个字节 110xxxxx 10xxxxxx
1110开头三个字节 1110xxxx 10xxxxxx 10xxxxxx

所以在现实中编码问题总是如此转换的
GBK -> unicode -> utf-8

乱码原因
1.解码与实际编码方式不一致
2.编码过程中丢失信息

对于数据库来说,有一个连接器的概念,这个连接器的作用就是中转客服端和服务端的编码和解码规则的。

所以对于mysql来说有如下三种编码字符集要设置
client/connection/server
对于mysql来说 提供的cmd工具还有一个result字符集的概念

因此client --> connection
如果connection < client的字符集 那么就可能在这个过程中丢失信息
如果想要三者一致,可以简写 set names utf-8

另外有一种编码,bom信息是为了辨认编码规则的,utf-8有的有bom头

七.阿里mysql说明

1.基础规范
1)必须使用 InnoDB 存储引擎
解读:支持事务、行级锁、并发性能更好、CPU 及内存缓存页优化使得资源利用率更高
2)使用 utf8mb4 字符集
解读:万国码,无需转码,无乱码风险,可存储 emoji
3)禁止使用存储过程、视图、触发器、Event
解读:高并发大数据的互联网业务,架构设计思路是 “解放数据库 CPU,将计算转移到服务层”,并发量大的情况下,这些功能很可能将数据库拖死,业务逻辑放到服务层具备更好的扩展性,能够轻易实现 “增机器就加性能”。数据库擅长存储与索引,CPU 计算还是上移吧
4)禁止存储大文件或者大照片
解读:为何要让数据库做它不擅长的事情?大文件和照片存储在文件系统,数据库里存 URI 多好
2.命名规范
(5)库名、表名、字段名:小写,下划线风格,不超过 32 个字符,必须见名知意,禁止拼音英文混用

1.后缀与类型:
	a.项目中 id、status、type 字段名明确为数字枚举类型。
	b.time 时间型、date 日期型,譬如:不要使用 start_date 作为一个时间型字段。
	c.status、type 为整型,使用枚举。
	d.key、title、label、name、description、uri、url 等为字符型。
	e.id 为数字类型。

2.不要使用对象名作为简单类型的字段名,为其增加可识别其类型的后缀,如:uri、key 等。
	a.头像不要使用 avatar 作为字段名,使用 avatar_key 或者 avatar_url。
	b.字段名 user 不知道是 user_id 还是 user_name。
	
(6)索引名 idx_xxx,唯一索引名 uniq_xxx
3.表设计规范
(7)单实例表数目必须小于 500
(8)单表列数目必须小于 30
(9)表必须有主键,例如自增主键
解读:
a)主键递增,数据行写入可以提高插入性能,可以避免 page 分裂,减少表碎片提升空间和内存的使用
b)主键要选择较短的数据类型, Innodb 引擎普通索引都会保存主键的值,较短的数据类型可以有效的减少索引的磁盘空间,提高索引的缓存效率
c) 无主键的表删除,在 row 模式的主从架构,会导致备库夯住
10)性能优先的表禁止使用外键,如果有外键完整性约束,需要应用程序控制
解读:外键会导致表与表之间耦合,update 与 delete 操作都会涉及相关联的表,十分影响 sql 的性能,甚至会造成死锁。高并发情况下容易造成数据库性能,大数据高并发业务场景数据库使用以性能优先
4.字段设计规范
1.时间型字段应该如何选择?DATETIME、TIMESTAMP、BITINT 
正常情况下使用 DATETIME 类型,并在字段的注释中记录下该字段对应的时区。时区的话应用程序自己来			处理就好了,不要依赖数据库帮忙来处理。
可以使用 BIGINT 存储「UNIX 时间戳」,时区的话应用程序来处理。
使用 TIMESTAMP 必须要注意 time zone 的设置,应用程序与数据库的 time zone 要一致,如:在做跨国数据同步的时候国内的服务要读写国外的数据库,国内服务是 UTC+8,国外数据库是 UTC,会出现问题。
解读:
a.datetime:占用 8 个字节
	1)允许为空值,可以自定义值,系统不会自动修改其值。
	2)实际格式储存与时区无关(Just stores what you have stored and retrieves the same thing which you have stored. It has nothing to deal with the TIMEZONE and Conversion.)
	3)可以使用 MySQL 提供的日期函数。
	4)MySQL 5.6.5 之前是无法使用DEFAULT 和 ON UPDATE 等机制,5.6.5 后可以。
b.timestamp:占用4个字节
	1)允许为空值,自定义与 MySQL 版本有关
	2)TIMESTAMP 值不能早于 1970 或晚于 2037。这说明一个日期,例如'1968-01-01',虽然对于 DATETIME 或 DATE 值是有效的,但对于 TIMESTAMP 值却无效,如果分配给这样一个对象将被转换为 0
	3)值以 UTC 格式保存( it stores the number of milliseconds),存储时会发生时区转化 ,存储时对当前的时区进行转换,检索时再转换回当前的时区。
	4)可以使用如 ON UPDATE 等自动更新字段值的机制;MySQL 5.6.5 之前每张表 DEFAULT 和 ON UPDATE 只能使用一种

2.布尔类型如何选择?
对于 MySQL 来说,BOOL and BOOLEAN are synonyms of TINYINT(1)

3.不需要检索、过滤的字段、不需要进行原子操作或者附加 MySQL 函数来操作的字段可以放到 JSON/PROTOBUF/THRIFT/MSGPACK 格式的 DATA/EXTRA 字段中。
解读:可以避免频繁地改表。

4.存储层不要存储多余的数据
解读:协议层用的数据(譬如 key),可以通过 id 计算出来的(key = user-<id>@alibaba.com),可以不要 key 这个字段

11)必须把字段定义为 NOT NULL 并且提供默认值
解读:
a)null 的列使索引 / 索引统计 / 值比较都更加复杂,对 MySQL 来说更难优化
b)null 这种类型 MySQL 内部需要进行特殊处理,增加数据库处理记录的复杂性;同等条件下,表中有较多空字段的时候,数据库的处理性能会降低很多
c)null 值需要更多的存储空,无论是表还是索引中每行中的 null 的列都需要额外的空间来标识
d)对 null 的处理时候,只能采用 is null 或 is not null,而不能采用 =、in、<、<>、!=、not in 这些操作符号。如:where name!=’shenjian’,如果存在 name 为 null 值的记录,查询结果就不会包含 name 为 null 值的记录

12)禁止使用 TEXT、BLOB 类型
解读:会浪费更多的磁盘和内存空间,非必要的大量的大字段查询会淘汰掉热数据,导致内存命中率急剧降低,影响数据库性能

13)禁止使用小数存储货币
解读:使用整数吧,小数容易导致钱对不上

14)必须使用 varchar(20) 存储手机号
解读:
a)涉及到区号或者国家代号,可能出现 +-()
b)手机号会去做数学运算么?
c)varchar 可以支持模糊查询,例如:like“138%”

15)禁止使用 ENUM,可使用 TINYINT 代替
解读:
a)增加新的 ENUM 值要做 DDL 操作
b)ENUM 的内部实际存储就是整数,你以为自己定义的是字符串?
5.索引设计规范
16)单表索引建议控制在 5 个以内

17)单索引字段数不允许超过 5 个
解读:字段超过 5 个时,实际已经起不到有效过滤数据的作用了

18)禁止在更新十分频繁、区分度不高的属性上建立索引
解读:
a)更新会变更 B+ 树,更新频繁的字段建立索引会大大降低数据库性能
b)“性别” 这种区分度不大的属性,建立索引是没有什么意义的,不能有效过滤数据,性能与全表扫描类似

19)建立组合索引,必须把区分度高的字段放在前面
解读:能够更加有效的过滤数据
6.SQL使用规范
20)禁止使用 SELECT *,只获取必要的字段,需要显示说明列属性
解读:
a)读取不需要的列会增加 CPU、IO、NET 消耗
b)不能有效的利用覆盖索引
c)使用 SELECT * 容易在增加或者删除字段后出现程序 BUG

21)禁止使用 INSERT INTO t_xxx VALUES(xxx),必须显示指定插入的列属性
解读:容易在增加或者删除字段后出现程序 BUG

22)禁止使用属性隐式转换
解读:SELECT uid FROM t_user WHERE phone=13812345678 会导致全表扫描,而不能命中 phone 索引,猜猜为什么?(这个线上问题不止出现过一次)
隐式转换:查询类型要和存储类型一致。

23)禁止在 WHERE 条件的属性上使用函数或者表达式
解读:SELECT uid FROM t_user WHERE from_unixtime(day)>='2017-02-15' 会导致全表扫描
正确的写法是:SELECT uid FROM t_user WHERE day>= unix_timestamp('2017-02-15 00:00:00')

24)禁止负向查询,以及 % 开头的模糊查询
解读:
a)负向查询条件:NOT、!=、<>、!<、!>、NOT IN、NOT LIKE 等,会导致全表扫描
b)% 开头的模糊查询,会导致全表扫描

25)禁止大表使用 JOIN 查询,禁止大表使用子查询
解读:会产生临时表,消耗较多内存与 CPU,极大影响数据库性能

26)禁止使用 OR 条件,必须改为 IN 查询
解读:旧版本 Mysql 的 OR 查询是不能命中索引的,即使能命中索引,为何要让数据库耗费更多的 CPU 帮助实施查询优化呢?

27)应用程序必须捕获 SQL 异常,并有相应处理
八.其它

1.查看建表语句
Show Create Table table_name

2.查看索引状态
Show Index From table_name

3.查看执行效率
Explain

每个字段的信息详解:http://www.cnblogs.com/xuanzhi201111/p/4175635.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值