15个MySQL常用基本SQL语句

15个MySQL常用基本SQL语句,第1张

在学习SQL语句之前,首先需要区分几个概念,我们常说的数据库是指数据库软件,例如MySQL、Oracle、SQL Server等,而本文提到的数据库是指数据库软件中的一个个用于存储数据的容器。

在MySQL中,数据库称为database,数据表称为table,一个数据库软件中有多个数据库(databases),每个数据库中又可以有多个数据表(tables),最终,数据是存储在数据表中。

数据库和数据表之间的关系可以用下面这个图来表示,对于一个数据库来说,有多个数据表。

在正式开始写SQL语句之前,需要说明两点。

这里通过MySQL Workbench来写SQL代码,在Workbench中,执行一条SQL语句的方式有两种。

了解了这之后,接下来介绍一些常见的命令,分两部分:数据库常用命令和数据表常用命令。

1、查看有哪些数据库

2、创建数据库

创建一个名为Testdb的数据库。

3、创建数据库并指定编码格式

有些时候,为了防止中文乱码,创建数据库的时候需要指定编码格式。

4、使用某个数据库

使用mydb这个数据库,或者进入mydb这个数据库。

5、删除数据库

删除Testdb这个数据库。

1、查看有哪些数据表

进入某个数据库之后,想查看有哪些数据表,SQL语句为:

mydb是一个新建的数据库,所以自然是没有数据表。

2、创建数据表

建表SQL语句格式为:

说明: 每个字段以逗号分隔,最后一个字段不加逗号。

例如,给定一个学员信息表,如下表所示。

根据以上表格,建表SQL语句如下。

以上语句中,primary key表示主键,意思是这个字段作为记录的唯一标识,就像每个人的身份z号,都是唯一确定的。

3、查看表结构

查看表结构的SQL命令为:

执行该命令会显示表stuinfo的基本结构,例如有哪些字段,每个字段是什么类型,谁是主键等。

4、修改数据表

修改数据表通过drop子句进行,比如,建完表后,想增加一个字段,SQL语句的格式为:

想在指定位置增加一个字段,例如,在某个字段后增加一个字段,SQL语句的格式为:

如果在某个字段之前增加字段,用before即可。

例如,在字段age后增加一个字段major(专业),SQL语句为:

执行这个命令,再通过describe查看表结构,会发现表中多了一个字段major。

如果要删除major这个字段,通过drop子句,SQL语句为:

5、重命名表

重命名表通过alter+rename来实现,SQL语句格式为:

这里为了不影响之前创建的表,我们创建一个新表,SQL语句如下。

以上创建一个名为stuInfoTest的表,现在想将它的名称改成stuinfotest1,SQL语句为:

6、删除数据表

删除数据表通过drop进行,SQL语句格式为:

例如,删除数据表stuinfotest1,SQL语句为:

7、插入记录

此时的表stuinfo是空的,没有数据,我们要向表中插入记录。

插入记录通过insert into进行,SQL语句格式为:

例如,向表stuinfo插入一条记录,SQL语句为:

注意:上方是一条SQL语句,为了可读性换行,记住一条SQL语句默认以分号结尾。

如果需要一次性插入多条记录,SQL语句格式为:

例如,向表stuinfo再插入两条记录,SQL语句为:

注意:如果设置了主键,插入记录的主键字段是不能重复的,也就是不能插入重复的记录。

作业:大家可以按照上述方法将上面的学员信息表中的所有记录都插入表stuinfo中。

8、查询记录

有了数据之后,就可以查询记录了,查询记录通过select子句进行。

例如,想查询表stuinfo中的所有记录,SQL语句为:

执行之后,就可以看到表stuinfo中的所有记录了。

如果想查询符合某个条件的记录,就要用到where子句了,SQL格式为:

例如,想查询stuid为20161001的记录,SQL语句为:

9、删除记录

删除记录通过delete子句进行,SQL语句格式为:

例如,想删除stuid为20161002的记录,SQL语句为:

10、修改记录

修改记录通过update子句进行,update就是更新的意思,SQL语句格式为:

例如,想将学号(stuid)为20161001的记录的姓名(stuname)更新为Jack,SQL语句为:

以上,就是MySQL中的基本SQL语句。

零基础如何学习数据分析?查看下方专栏。

一、 简单查询

简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句。它们分别说明所查询列、查询的表或视图、以及搜索条件等。

例如,下面的语句查询testtable表中姓名为"张三"的nickname字段和email字段。

SELECT nickname,email

FROM testtable

WHERE name='张三'

(一) 选择列表

选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变量和全局变量)等构成。

1、选择所有列

例如,下面语句显示testtable表中所有列的数据:

SELECT *

FROM testtable

2、选择部分列并指定它们的显示次序

查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。

例如:

SELECT nickname,email

FROM testtable

3、更改列标题

在选择列表中,可重新指定列标题。定义格式为:

列标题=列名

列名 列标题

如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列标题:

SELECT 昵称=nickname,电子邮件=email

FROM testtable

4、删除重复行

SELECT语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重复的数据行,默认为ALL。使用DISTINCT选项时,对于所有重复的数据行在SELECT返回的结果集合中只保留一行。

5、限制返回的行数

使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是表示一百分数,指定返回的行数等于总行数的百分之几。

例如:

SELECT TOP 2 *

FROM testtable

SELECT TOP 20 PERCENT *

FROM testtable

(二)FROM子句

FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,它们之间用逗号分隔。

在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应使用下面语句格式加以限定:

SELECT username,citytable.cityid

FROM usertable,citytable

WHERE usertable.cityid=citytable.cityid

在FROM子句中可用以下两种格式为表或视图指定别名:

表名 as 别名

表名 别名

(二) FROM子句

FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图,它们之间用逗号分隔。

在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应使用下面语句格式加以限定:

SELECT username,citytable.cityid

FROM usertable,citytable

WHERE usertable.cityid=citytable.cityid

在FROM子句中可用以下两种格式为表或视图指定别名:

表名 as 别名

表名 别名

例如上面语句可用表的别名格式表示为:

SELECT username,b.cityid

FROM usertable a,citytable b

WHERE a.cityid=b.cityid

SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查询数据。

例如:

SELECT a.au_fname+a.au_lname

FROM authors a,titleauthor ta

(SELECT title_id,title

FROM titles

WHERE ytd_sales>10000

) AS t

WHERE a.au_id=ta.au_id

AND ta.title_id=t.title_id

此例中,将SELECT返回的结果集合给予一别名t,然后再从中检索数据。

(三) 使用WHERE子句设置查询条件

WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据:

SELECT *

FROM usertable

WHERE age>20

WHERE子句可包括各种条件运算符:

比较运算符(大小比较):>、>=、=、<、<=、<>、!>、!<

范围运算符(表达式值是否在指定的范围):BETWEEN...AND...

NOT BETWEEN...AND...

列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2......)

NOT IN (项1,项2......)

模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE

空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL

逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR

1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30

2、列表运算符例:country IN ('Germany','China')

3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、varchar、text、ntext、datetime和smalldatetime等类型查询。

可使用以下通配字符:

百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。

下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。

方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。

例如:

限制以Publishing结尾,使用LIKE '%Publishing'

限制以A开头:LIKE '[A]%'

限制以A开头外:LIKE '[^A]%'

4、空值判断符例WHERE age IS NULL

5、逻辑运算符:优先级为NOT、AND、OR

(四)查询结果排序

使用ORDER BY子句对查询返回的结果按一列或多列排序。ORDER BY子句的语法格式为:

ORDER BY {column_name [ASC|DESC]} [,...n]

其中ASC表示升序,为默认值,DESC为降序。ORDER BY不能按ntext、text和image数据类型进行排

序。

例如:

SELECT *

FROM usertable

ORDER BY age desc,userid ASC

另外,可以根据表达式进行排序。

二、 联合查询

UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联合查询。UNION的语法格式为:

select_statement

UNION [ALL] selectstatement

[UNION [ALL] selectstatement][...n]

其中selectstatement为待联合的SELECT查询语句。

ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一行。

联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。

在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类型,系统将低精度的数据类型转换为高精度的数据类型。

在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如:

查询1 UNION (查询2 UNION 查询3)

三、连接查询

通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。

在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在一个表中。当检索数据时,通过连接 *** 作查询出存放在多个表中的不同实体的信息。连接 *** 作给用户带来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进行查询。

连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于将连接 *** 作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这种方法。

SQL-92标准所定义的FROM子句的连接语法格式为:

FROM join_table join_type join_table

[ON (join_condition)]

其中join_table指出参与连接 *** 作的表名,连接可以对同一个表 *** 作,也可以对多表 *** 作,对同一个表 *** 作的连接又称做自连接。

join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比较运算符进行表间某(些)列数据的比较 *** 作,并列出这些表中与连接条件相匹配的数据行。根据所使用的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的数据行。

交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。

连接 *** 作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑运算符等构成。

无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接连接。例如:

SELECT p1.pub_id,p2.pub_id,p1.pr_info

FROM pub_info AS p1 INNER JOIN pub_info AS p2

ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info)

(一)内连接

内连接查询 *** 作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分三种:

1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接表中的所有列,包括其中的重复列。

2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些运算符包括>、>=、<=、<、!>、!<和<>。

3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询结果集合中所包括的列,并删除连接表中的重复列。

例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社:

SELECT *

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state):

SELECT a.*,p.pub_id,p.pub_name,p.country

FROM authors AS a INNER JOIN publishers AS p

ON a.city=p.city

(二)外连接

内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。如下面使用左外连接将论坛内容和作者信息连接起来:

SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b

ON a.username=b.username

下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市:

SELECT a.*,b.*

FROM city as a FULL OUTER JOIN user as b

ON a.username=b.username

(三)交叉连接

交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等于6*8=48行。

SELECT type,pub_name

FROM titles CROSS JOIN publishers

ORDER BY type

mysql创建表字段长度范围_Mysql的建表规范与注意事项⼀、 表设计规范

库名、表名、字段名必须使⽤⼩写字母,“_”分割。

库名、表名、字段名必须不超过12个字符。

库名、表名、字段名见名知意,建议使⽤名词⽽不是动词。

建议使⽤InnoDB存储引擎。

存储精确浮点数必须使⽤DECIMAL替代FLOAT和DOUBLE。

建议使⽤UNSIGNED存储⾮负数值。

建议使⽤INT UNSIGNED存储IPV4。

整形定义中不添加长度,⽐如使⽤INT,⽽不是INT(4)。

使⽤短数据类型,⽐如取值范围为0-80时,使⽤TINYINT UNSIGNED。

不建议使⽤ENUM类型,使⽤TINYINT来代替。

尽可能不使⽤TEXT、BLOB类型。

VARCHAR(N),N表⽰的是字符数不是字节数,⽐如VARCHAR(255),可以最⼤可存储255个汉字,需要根据实际的宽度来选择N。

VARCHAR(N),N尽可能⼩,因为MySQL⼀个表中所有的VARCHAR字段最⼤长度是65535个字节,进⾏排序和创建临时表⼀类的内存 *** 作时,会使⽤N的长度申请内存。

表字符集选择UTF8。

使⽤VARBINARY存储变长字符串。

存储年使⽤YEAR类型。

存储⽇期使⽤DATE类型。

存储时间(精确到秒)建议使⽤TIMESTAMP类型,因为TIMESTAMP使⽤4字节,DATETIME使⽤8个字节。

建议字段定义为NOT NULL。

将过⼤字段拆分到其他表中。

禁⽌在数据库中使⽤VARBINARY、BLOB存储图⽚、⽂件等。

表结构变更需要通知DBA审核。

⼆、 索引规范

⾮唯⼀索引必须按照“idx_字段名称_字段名称[_字段名]”进⾏命名。

唯⼀索引必须按照“uniq_字段名称_字段名称[_字段名]”进⾏命名。

索引名称必须使⽤⼩写。

索引中的字段数建议不超过5个。

单张表的索引数量控制在5个以内。

唯⼀键由3个以下字段组成,并且字段都是整形时,使⽤唯⼀键作为主键。

没有唯⼀键或者唯⼀键不符合5中的条件时,使⽤⾃增(或者通过发号器获取)id作为主键。

唯⼀键不和主键重复。

索引字段的顺序需要考虑字段值去重之后的个数,个数多的放在前⾯。

ORDER BY,GROUP BY,DISTINCT的字段需要添加在索引的后⾯。

使⽤EXPLAIN判断SQL语句是否合理使⽤索引,尽量避免extra列出现:Using File Sort,UsingTemporary。

UPDATE、DELETE语句需要根据WHERE条件添加索引。

不建议使⽤%前缀模糊查询,例如LIKE “%weibo”。

对长度过长的VARCHAR字段建⽴索引时,添加crc32或者MD5 Hash字段,对Hash字段建⽴索引。

合理创建联合索引(避免冗余),(a,b,c) 相当于 (a) 、(a,b) 、(a,b,c)。

合理利⽤覆盖索引。

SQL变更需要确认索引是否需要变更并通知DBA。

三、 SQL语句规范

使⽤prepared statement,可以提供性能并且避免SQL注⼊。

SQL语句中IN包含的值不应过多。

UPDATE、DELETE语句不使⽤LIMIT。

WHERE条件中必须使⽤合适的类型,避免MySQL进⾏隐式类型转化。

SELECT语句只获取需要的字段。

SELECT、INSERT语句必须显式的指明字段名称,不使⽤SELECT *,不使⽤INSERTINTO table()。

使 ⽤SELECT column_name1, column_name2 FROM table WHERE[condition]⽽不是SELECT column_name1 FROM table WHERE[condition]和SELECT column_name2 FROM table WHERE [condition]。

WHERE条件中的⾮等值条件(IN、BETWEEN、、>=)会导致后⾯的条件使⽤不了索引。

避免在SQL语句进⾏数学运算或者函数运算,容易将业务逻辑和DB耦合在⼀起。

INSERT语句使⽤batch提交(INSERT INTO tableVALUES(),(),()……),values的个数不应过多。

避免使⽤存储过程、触发器、函数等,容易将业务逻辑和DB耦合在⼀起,并且MySQL的存储过程、触发器、函数中存在⼀定的bug。

避免使⽤JOIN。

使⽤合理的SQL语句减少与数据库的交互次数。

不使⽤ORDER BY RAND(),使⽤其他⽅法替换。

建议使⽤合理的分页⽅式以提⾼分页的效率。

统计表中记录数时使⽤COUNT(*),⽽不是COUNT(primary_key)和COUNT(1)。

禁⽌在从库上执⾏后台管理和统计类型功能的QUERY。

四、 散表规范

每张表数据量建议控制在5000w以下。

可以结合使⽤hash、range、lookup table进⾏散表。

散表如果使⽤md5(或者类似的hash算法)进⾏散表,表名后缀使⽤16进制,⽐如user_ff。

推荐使⽤CRC32求余(或者类似的算术算法)进⾏散表,表名后缀使⽤数字,数字必须从0开始并等宽,⽐如散100张表,后缀从00-99。

使⽤时间散表,表名后缀必须使⽤特定格式,⽐如按⽇散表user_20110209、按⽉散表user_201102。

五、 其他

批量导⼊、导出数据需要DBA进⾏审查,并在执⾏过程中观察服务。

批量更新数据,如update,delete *** 作,需要DBA进⾏审查,并在执⾏过程中观察服务。

产品出现⾮数据库平台运维导致的问题和故障时,如前端被抓站,请及时通知DBA,便于维护服务稳定。

业务部门程序出现bug等影响数据库服务的问题,请及时通知DBA,便于维护服务稳定。

业务部门推⼴活动,请提前通知DBA进⾏服务和访问评估。

如果出现业务部门⼈为误 *** 作导致数据丢失,需要恢复数据,请在第⼀时间通知DBA,并提供准确时间,误 *** 作语句等重要线索。

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

FAQ

1-1.库名、表名、字段名必须使⽤⼩写字母,“_”分割。

a)MySQL有配置参数lower_case_table_names,不可动态更改,Linux系统默认为0,即库表名以实际情况存储,⼤⼩写敏感。如果是1,以⼩写存储,⼤⼩写不敏感。如果是2,以实际情况存储,但以⼩写⽐较。

b) 如果⼤⼩写混合⽤,可能存在abc,Abc,ABC等多个表共存,容易导致混乱。

c) 字段名显⽰区分⼤⼩写,但实际使⽤不区分,即不可以建⽴两个名字⼀样但⼤⼩写不⼀样的字段。

d) 为了统⼀规范, 库名、表名、字段名使⽤⼩写字母。

1-2.库名、表名、字段名必须不超过12个字符。

库名、表名、字段名⽀持最多64个字符,但为了统⼀规范、易于辨识以及减少传输量,必须不超过12字符。

1-3.库名、表名、字段名见名知意,建议使⽤名词⽽不是动词。

a) ⽤户评论可⽤表名usercomment或者comment。

b) 库表是⼀种客观存在的事物,⼀种对象,所以建议使⽤名词。

1-4.建议使⽤InnoDB存储引擎。

a) 5.5以后的默认引擘,⽀持事务,⾏级锁,更好的恢复性,⾼并发下性能更好,对多核,⼤内存,ssd等硬件⽀持更好。

b) 具体⽐较可见附件的官⽅⽩⽪书。

1-5.存储精确浮点数必须使⽤DECIMAL替代FLOAT和DOUBLE。

a) mysql中的数值类型(不包括整型):

IEEE754浮点数:float (单精度) , double 或real (双精度)

定点数: decimal或 numeric

单精度浮点数的有效数字⼆进制是24位,按⼗进制来说,是8位;双精度浮点数的有效数字⼆进制是53位,按⼗进制来说,是16 位

⼀个实数的有效数字超过8位,⽤单精度浮点数来表⽰的话,就会产⽣误差!同样,如果⼀个实数的有效数字超过16位,⽤双精度浮点数来表⽰,也会产⽣误差

b)IEEE754标准的计算机浮点数,在内部是⽤⼆进制表⽰的,但在将⼀个⼗进制数转换为⼆进制浮点数时,也会造成误差,原因是不是所有的数都能转换成有限长度的⼆进制数。

即⼀个⼆进制可以准确转换成⼗进制,但⼀个带⼩数的⼗进制不⼀定能够准确地⽤⼆进制来表⽰。

实例:

drop table if exists t

create table t(value float(10,2))

insert into t values(131072.67),(131072.68)

select value from t

+-----------+

|value |

+-----------+

| 131072.67 |

| 131072.69 |

+-----------+

1-6.建议使⽤UNSIGNED存储⾮负数值。

同样的字节数,存储的数值范围更⼤。如tinyint 有符号为 -128-127,⽆符号为0-255

1-7. 如何使⽤INT UNSIGNED存储ip?

使⽤INTUNSIGNED⽽不是char(15)来存储ipv4地址,通过MySQL函数inet_ntoa和inet_aton来进⾏转化。Ipv6地址⽬前没有转化函数,需要使⽤DECIMAL或者两个bigINT来存储。例如:

SELECT INET_ATON('209.207.224.40')

3520061480

SELECT INET_NTOA(3520061480)

209.207.224.40

1-8. INT[M],M值代表什么含义?

注意数值类型括号后⾯的数字只是表⽰宽度⽽跟存储范围没有关系,⽐如INT(3)默认显⽰3位,空格补齐,超出时正常显⽰,Python、Java客户端等不具备这个功能。

1-10.不建议使⽤ENUM、SET类型,使⽤TINYINT来代替。

a)ENUM,有三个问题:添加新的值要做DDL,默认值问题(将⼀个⾮法值插⼊ENUM(也就是说,允许的值列之外的字符串),将插⼊空字符串以作为特殊错误值),索引值问题(插⼊数字实际是插⼊索引对应的值)

实例:

drop table if exists t

create table t(sex enum('0','1'))

insert into t values(1)

insert into t values('3')

select * from t

+------+

| sex |

+------+

| 0 |

| |

+------+

2 rows in set (0.00 sec)

1-11.尽可能不使⽤TEXT、BLOB类型。

a) 索引排序问题,只能使⽤max_sort_length的长度或者⼿⼯指定ORDER BY SUBSTRING(column,length)的长度来排序

b) Memory引擘不⽀持text,blog类型,会在磁盘上⽣成临时表

c) 可能浪费更多的空间

d) 可能⽆法使⽤adaptive hash index

e) 导致使⽤where没有索引的语句变慢

1-13. VARCHAR中会产⽣额外存储吗?

VARCHAR(M),如果M<256时会使⽤⼀个字节来存储长度,如果M>=256则使⽤两个字节来存储长度。

1-14.表字符集选择UTF8。

a) 使⽤utf8字符集,如果是汉字,占3个字节,但ASCII码字符还是1个字节。

b) 统⼀,不会有转换产⽣乱码风险

c) 其他地区的⽤户(美国、印度、台湾)⽆需安装简体中⽂⽀持,就能正常看您的⽂字,并且不会出现乱码

d)ISO-8859-1编码(latin1)使⽤了单字节内的所有空间,在⽀持ISO-8859-1的系统中传输和存储其他任何编码的字节流都不会被抛弃。即把其他任何编码的字节流当作ISO-8859-1编码看待都没有问题,保存的是原封不动的字节流。

1-15.使⽤VARBINARY存储变长字符串。

⼆进制字节流,不存在编码问题

1-18. 为什么建议使⽤TIMESTAMP来存储时间⽽不是DATETIME?

DATETIME和TIMESTAMP都是精确到秒,优先选择TIMESTAMP,因为TIMESTAMP只有4个字节,⽽DATETIME8个字节。同时TIMESTAMP具有⾃动赋值以及⾃动更新的特性。

如何使⽤TIMESTAMP的⾃动赋值属性?

a) 将当前时间作为ts的默认值:ts TIMESTAMP DEFAULTCURRENT_TIMESTAMP。

b) 当⾏更新时,更新ts的值:ts TIMESTAMP DEFAULT 0 ONUPDATE CURRENT_TIMESTAMP。

c) 可以将1和2结合起来:ts TIMESTAMP DEFAULTCURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP。

1-19.建议字段定义为NOT NULL。

a)如果null字段被索引,需要额外的1字节

b)使索引,索引统计,值的⽐较变得更复杂

c)可⽤0,''代替

d)如果是索引字段,⼀定要定义为not null

1-21.禁⽌在数据库中使⽤VARBINARY、BLOB存储图⽚、⽂件等。

采⽤分布式⽂件系统更⾼效

2. 为什么MySQL的性能依赖于索引?

MySQL的查询速度依赖良好的索引设计,因此索引对于⾼性能⾄关重要。合理的索引会加快查询速度(包括UPDATE和DELETE的速

度,MySQL会将包含该⾏的page加载到内存中,然后进⾏UPDATE或者DELETE *** 作),不合理的索引会降低速度。

MySQL索引查找类似于新华字典的拼⾳和部⾸查找,当拼⾳和部⾸索引不存在时,只能通过⼀页⼀页的翻页来查找。当MySQL查询不能使⽤索引时,MySQL会进⾏全表扫描,会消耗⼤量的IO。

2-5. 为什么⼀张表中不能存在过多的索引?

InnoDB的secondaryindex使⽤b+tree来存储,因此在UPDATE、DELETE、INSERT的时候需要对b+tree进⾏调整,过多的索引会减慢更新的速度。

2-11. EXPLAIN语句

EXPLAIN语句(在MySQL客户端中执⾏)可以获得MySQL如何执⾏SELECT语句的信息。通过对SELECT语句执⾏EXPLAIN,可以知晓MySQL执⾏该SELECT语句时是否使⽤了索引、全表扫描、临时表、排序等信息。尽量避免MySQL进⾏全表扫描、使⽤临时表、排序等。详见官⽅⽂档。

2-13.不建议使⽤%前缀模糊查询,例如LIKE “%weibo”。

会导致全表扫描

2-14. 如何对长度⼤于50的VARCHAR字段建⽴索引?

下⾯的表增加⼀列url_crc32,然后对url_crc32建⽴索引,减少索引字段的长度,提⾼效率。

CREATE TABLE url(

……

url VARCHAR(255) NOT NULL DEFAULT 0,

url_crc32INT UNSIGNED NOT NULL DEFAULT 0,

……

index idx_url(url_crc32)

)

2-16. 什么是覆盖索引?

InnoDB 存储引擎中,secondaryindex(⾮主键索引)中没有直接存储⾏地址,存储主键值。如果⽤户需要查询secondaryindex中所不包含的数据列时,需要先通过secondaryindex查找到主键值,然后再通过主键查询到其他数据列,因此需要查询两次。

覆盖索引的概念就是查询可以通过在⼀个索引中完成,覆盖索引效率会⽐较⾼,主键查询是天然的覆盖索引。

合理的创建索引以及合理的使⽤查询语句,当使⽤到覆盖索引时可以获得性能提升。

⽐如SELECT email,uid FROM user_email WHEREuid=xx,如果uid不是主键,适当时候可以将索引添加为index(uid,email),以获得性能提升。

3-3.UPDATE、DELETE语句不使⽤LIMIT。

a) 可能导致主从数据不⼀致

b) 会记录到错误⽇志,导致⽇志占⽤⼤量空间

3-4. 为什么需要避免MySQL进⾏隐式类型转化?

因为MySQL进⾏隐式类型转化之后,可能会将索引字段类型转化成=号右边值的类型,导致使⽤不到索引,原因和避免在索引字段中使⽤函数是类似的。

3-6. 为什么不建议使⽤SELECT *?

增加很多不必要的消耗(cpu、io、内存、⽹络带宽);增加了使⽤覆盖索引的可能性;当表结构发⽣改变时,前段也需要更新。

3-13. 如何减少与数据库的交互次数?

使⽤下⾯的语句来减少和db的交互次数:

INSERT ... ON DUPLICATE KEY UPDATE

REPLACE

INSERT IGNORE

INSERT INTO values(),()如何结合使⽤多个纬度进⾏散表散库?

例如微博message,先按照crc32(message_id)将message散到16个库中,然后针对每个库中的表,⼀天⽣成⼀张新表。

3-14. 为什么不能使⽤ORDER BY rand()?

因为ORDER BYrand()会将数据从磁盘中读取,进⾏排序,会消耗⼤量的IO和CPU,可以在程序中获取⼀个rand值,然后通过在从数据库中获取对应的值。

3-15. MySQL中如何进⾏分页?

假如有类似下⾯分页语句:

SELECT * FROM table ORDER BY TIME DESC LIMIT 10000,10

这种分页⽅式会导致⼤量的io,因为MySQL使⽤的是提前读取策略。

推荐分页⽅式:

SELECT * FROM table WHERE TIME

SELECT * FROM tableinner JOIN(SELECT id FROM table ORDER BY TIME LIMIT 10000,10) as t USING(id)

3-17.为什么避免使⽤复杂的SQL?

拒绝使⽤复杂的SQL,将⼤的SQL拆分成多条简单SQL分步执⾏。原因:简单的SQL容易使⽤到MySQL的querycache;减少锁表时间特别是MyISAM;可以使⽤多核cpu。

2. InnoDB存储引擎为什么避免使⽤COUNT(*)?

InnoDB表避免使⽤COUNT(*) *** 作,计数统计实时要求较强可以使⽤memcache或者Redis,⾮实时统计可以使⽤单独统计表,定时更新。

5

百度文库VIP限时优惠现在开通,立享6亿+VIP内容

立即获取

mysql创建表字段长度范围_Mysql的建表规范与注意事项

mysql创建表字段长度范围_Mysql的建表规范与注意事项⼀、 表设计规范

库名、表名、字段名必须使⽤⼩写字母,“_”分割。

库名、表名、字段名必须不超过12个字符。

库名、表名、字段名见名知意,建议使⽤名词⽽不是动词。

建议使⽤InnoDB存储引擎。

存储精确浮点数必须使⽤DECIMAL替代FLOAT和DOUBLE。

建议使⽤UNSIGNED存储⾮负数值。

建议使⽤INT UNSIGNED存储IPV4。

第 1 页

整形定义中不添加长度,⽐如使⽤INT,⽽不是INT(4)。

使⽤短数据类型,⽐如取值范围为0-80时,使⽤TINYINT UNSIGNED。

不建议使⽤ENUM类型,使⽤TINYINT来代替。

尽可能不使⽤TEXT、BLOB类型。

VARCHAR(N),N表⽰的是字符数不是字节数,⽐如VARCHAR(255),可以最⼤可存储255个汉字,需要根据实际的宽度来选择N。

VARCHAR(N),N尽可能⼩,因为MySQL⼀个表中所有的VARCHAR字段最⼤长度是65535个字节,进⾏排序和创建临时表⼀类的内存 *** 作时,会使⽤N的长度申请内存。

第 2 页

表字符集选择UTF8。

使⽤VARBINARY存储变长字符串。

存储年使⽤YEAR类型。

存储⽇期使⽤DATE类型。

存储时间(精确到秒)建议使⽤TIMESTAMP类型,因为TIMESTAMP使⽤4字节,DATETIME使⽤8个字节。

建议字段定义为NOT NULL。

将过⼤字段拆分到其他表中。

禁⽌在数据库中使⽤VARBINARY、BLOB存储图⽚、⽂件等。

表结构变更需要通知DBA审核。

第 3 页

⼆、 索引规范

⾮唯⼀索引必须按照“idx_字段名称_字段名称[_字段名]”进⾏命名。

唯⼀索引必须按照“uniq_字段名称_字段名称[_字段名]”进⾏命名。

索引名称必须使⽤⼩写。

索引中的字段数建议不超过5个。

单张表的索引数量控制在5个以内。

唯⼀键由3个以下字段组成,并且字段都是整形时,使⽤唯⼀键作为主键。

没有唯⼀键或者唯⼀键不符合5中的条件时,使⽤⾃增(或者通过发号器获取)id作为主键。

第 4 页

唯⼀键不和主键重复。

索引字段的顺序需要考虑字段值去重之后的个数,个数多的放在前⾯。

ORDER BY,GROUP BY,DISTINCT的字段需要添加在索引的后⾯。

使⽤EXPLAIN判断SQL语句是否合理使⽤索引,尽量避免extra列出现:Using File Sort,UsingTemporary。

UPDATE、DELETE语句需要根据WHERE条件添加索引。

不建议使⽤%前缀模糊查询,例如LIKE “%weibo”。

对长度过长的VARCHAR字段建⽴索引时,添加crc32或者MD5 Hash字段,对Hash字段建⽴索引。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/8570189.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-18
下一篇2023-04-18

发表评论

登录后才能评论

评论列表(0条)

    保存