想更一进步的支持我,请扫描下方的二维码,你懂的~mysql
数据集合
。理解数据库最简单的方法是想象成一个文件柜。特定类型
数据的结构化清单
。表能够保存顾客清单、产品目录或者其余信息清单。特定类型
表示存储在表中的数据是一种类型的数据或一个清单,功能专注。决不该该把两种类型的表混合在一块儿。mysql
或者git
mysql -u username -p
而后输入密码正则表达式
建立库:算法
create database dbname;
删除库sql
drop database dbname;
选择数据库,使用use
关键字;如数据库
use kvseg;
SHOW DATABASES
返回可用的数据库的一个列表。segmentfault
SHOW TABLES
SHOW COLUMNS FROM customers
create database dbname; use dbname; source dir
dir是.sql文件的路径。若是不清楚路径能够输入pwd
指令查看当前路径安全
mysqldump -u root -p news > news.sql
select 子句顺序svg
子句 说明 select 要返回的列或表达式 from 从中检索数据的表 where 行级过滤 group by 分组说明 having 组级过滤 order by 输出排序顺序 limit 要检索的行数
为了使用select检索表数据,必须至少给两条信息 -- 想选择什么(哪一列),以及从什么地方(数据库)选择函数
select cust_name from customers;
select cust_id,cust_name from customers;
select * from products;
select distinct vend_id from products;
LIMIT
关键字select prod_name from products limit 5;
好比从行5开始的5行
select prod_name from products limit 55;
排序检索数据
使用select语句的order by 子句,根据须要排序检索出数据。
select * from products order by 列名(keyword for sorting)
order by 子句取一个或多个列的名字,据此对输出进行排序。
按照多个列排序时,排序彻底按照所规定的顺序进行。换句话说,对于上述中的输出,仅仅在多个行具备相同的segk(第一关键字)值时才对按照randnum(第二关键字)排序。
DESC
还能够实现按照第一个关键字降序,第二个关键字升序
DESC
只用到直接位于其前面的列明。若是想在多个列上进行降序排列,必须对每一个列指定DESC关键字。
IN A CONCLUSION: order by子句必须是select语句的最后一条子句。
op | descriptions |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< / > | 小于 / 大于 |
<= / >= | 小于等于/ 大于等于 |
Between | 在指定的两个值之间 |
is NULL | 空值检查 |
搜索条件/过滤条件
过滤出来的数据。mysqlselect * from products where prod_price = 55;
mysqlselect * from products where prod_price <> 55;
mysqlselect * from products where prod_price between 30 and 60;
mysqlselect * from products where prod_price is Null;
计算次序问题: 使用
圆括号
明确的分组相应的操做符。
好比选择segk 为118 或者 120的行,而且随机数小于等于2;
由于sql对and进行优先级处理。
任什么时候候后使用具备and 和 or操做符的where子句,都应该使用圆括号明确的分组操做符,不要过度依赖默认的计算次序。使用圆括号来消除歧义。
在where 条件中使用REGEXP关键字。
基本字符匹配
检索列prod_name 包含文本1000的全部行:
进行OR匹配
至关于:或操做 “|”
[
和]
括起来的字符来完成。[456]
定义了一组字符,他的意思是匹配4或5或6. []
是另外一种形式的OR语句。[456]
是[4|5|6]
的缩写。[1-3]
a-z
都是合法的范围、匹配特殊字符
正则表达式语言由特殊含义的特殊字符构成。
.
在正则表达式中表示匹配任何一个字符
好比匹配prod_name中包括on
字符串的行:
那如何匹配.
,[]
,|
,-
?
为了匹配特殊字符,必须用
\\
为前导。 好比\\.
表示查找·
匹配字符类
匹配多个实例
再好比 匹配连在一块儿的4位数字:
sticks?
: s
后的?
使s可选,由于?
匹配它前面紧跟的任何字符的0次或者1次出现。
[:digit:]
匹配任意数字,于是它为数字的一个集合。{4}
确切地要求它前面的字符出现4次。
因此[:digit:]{4}
匹配连在一块儿的任意4位数字。
定位符
目前为止全部例子都是匹配一个串中任意为止的文本。为了匹配特定为止的文本,须要使用定位符。
拼接字段
存储在数据库表中的数据通常不是应用程序所须要的格式。咱们须要直接从数据库中检索出转换、计算或格式化过
的数据;而不是检索出数据,而后再在客户机应用程序或报告程序中从新格式化。
计算字段(字段 = 列,不过数据库列通常称为列,而字段一般用于计算字段中)并不实际存在于数据库表中,计算字段是运行时在select语句内建立的。
拼接 concatenate 将值联结到一块儿构成单个值
在MySQL的select语句中,可以使用Concat()
函数来拼接两个列。
如建立由两列组成的标题:生成一个供应商报表,须要在供应商的名字中按照name(location)这样的格式列出供应商的位置。此报表须要单个值,而表中数据存储的两个列vend_name
和vend_country
中。还须要用括号将vend_country
括起来。
新建立的列用AS
赋一个别名
left() 串左边字符 length() 串长度 locate() 找出串的一个子串 lower() 转为小写 ltrim() 去掉左边空格 right() 返回串右边字符 rtrim() 去掉串右边空格 soundex() 返回字符串soundex值 upper() 大写
将选择的文本转换成大写
select Upper(vend_name) from vendors;
Soundex()
函数:将任何文本传转换为描述其语音表示的字母数字模式的算法。(语音匹配?对发音比较而不是对字幕比较)
日期和时间函数 adddate() 增长一个日期-天或周 addtime() 增长一个时间 curdate() 返回当前日期 curtime() 返回当前时间 date() 返回日期时间的日期部分 datediff() 计算两个日期差 date_add() 高度灵活的日期运算函数 date_format() 返回一个格式化的日期或时间串 day() 返回一个日期的天数部分 dayofweek() 对于一个日期,返回对应的星期几 hour() minute() month() now() 当前日期和时间 second() time() 当前日期时间的时间部分 year()
通常,应用程序不使用用来存储日期和时间的格式,所以日期和时间函数老是被用来读取,统计和处理这些值。
MySQL的日期格式:yyyy-mm-dd
。 好比 2005-09-01
可是这样的where order_date = '2005-09-01'
不可靠。由于order_date存储的数据类型是datatime. 这种类型存储日期及时间值。好比存储的order_date值为2005-09-01 11:30:05
,则where order_date = '2005-09-01'
就会匹配失败。
因此最安全的方法是Date()函数,Date(order_date)指示MySQL提取列的日期部分。
select cust_id, order_num from orders where Date(order_date) = '2005-09-01';
再好比想要检索出2005年9月下的全部订单。
select cust_id, order_num from orders where Year(order_date) = 2005 and Month(order_date) = 9;
咱们常常须要汇总函数,而不是把它们实际检索出来。
这种类型的检索例子:
1. 肯定表中行数
2. 得到表中行组的和
3. 找出表列(or 全部行某些特定的行)的最大值,最小值和平均值
汇集函数(aggregate function) 运行在行组上,计算和返回单个值的函数。
AVG() 返回某列的平均值 COUNT() 返回某列的行数 MAX() 返回某列的最大值 MIN() 返回某列的最小值 SUM() 返回某列值的和
select avg(prod_price) as avg_price from products;
- 计数
使用count(*)对表中行的数目进行计数(whether null or not)
使用count(column)对特定列具备值的行进行计数,忽略null
目前为止全部计算都是在表的全部数据或匹配特定的where子句的数据上进行的。
group by 子句指示MySQL分组数据,而后对每一个组进行汇集(计算)
,而不是整个结果集进行计算。
where 和 have 的区别:
where在分组前过滤,having在分组后过滤
1.group by 能够包含任意数目的列 2.group by 中每一个列都必须是检索列或有效的表达式(但不能使汇集函数) 3.除汇集函数外,select语句中的每一个列都必须在group by子句中出现 4.若是分组列有Null值,Null将做为一个分组返回 5.group by 子句必须出如今where子句以后, order by 以前
首先看products 这个表
主键是prod_id 产品id,每个产品都对应一个供应商ID,产品名,产品价格,以及简介。
若是咱们查看该产品表的供应商信息:
若是想进一步获知每一个供应商提供多少种产品,就应该对供应商进行分组: 好比供应商1001提供3种产品,供应商1002提供2种产品,供应商1003提供7种产品,供应商1005提供2种产品。
分组:
mysqlselect vend_id, count(*) as num_prods from products group by vend_id;
过滤分组
除了能用group by 分组数据外,还容许过滤分组,规定包括哪些分组,排除哪些分组。例如:可能想要列出至少有两个订单的全部顾客。为了得出这种数据,必须给予完整的分组,而不是个别的行进行过滤。
having
很是类where
, where
能作的having
都能作,惟一差异是where
过滤行,having
过滤分组。
下面列出订单表orders的状况,每一个表的主键是订单编号,每行还有订单日期和顾客id.
若是想要统计出订单数目超过2的顾客id
增长的having子句,过滤了count(*)>=2那些分组。
where
和having
组合使用,能够进行更强功能的操做。 如:列出提供了2个以上,价格为10以上的产品的供应商:
先用wehre子句过滤了全部价格至少为10的行,而后按照vend_id分组数据,having子句过滤计数为2或2以上的分组。
能够涉及数据库多个表,检索数据的语句。
子查询用作过滤 in
订单存储在两个表(orders,orderitems)中。
客户信息存储在customers表中
若是须要列出订购TNT2物品的全部客户:
须要包含以下步骤:
step 1. 检索包含物品TNT2的全部订单的编号。
step 2. 检索具备前一步骤列出的订单编号的全部客户ID
step 3. 检索前一步骤所返回的全部客户ID的信息
能够把一条select语句返回的结果用于另外一条select语句的where子句 -- 也可使用子查询来把3个查询组合成一条语句。
select * from customers where cust_id in (select cust_id from orders where order_num in (select order_num from orderitems where prod_id = 'TNT2'));
做为计算字段使用子查询
若是须要显示customers表中每一个客户的订单总数。 这须要使用customers,orders两个表。
使用select count(*) 对表中的行进行计数,并经过where 子句过滤行(经过过滤id)
orders是一个计算字段,它是由圆括号中的子查询创建的。该子查询对检索出的每一个客户执行一次。在这个例子中,该子查询执行了5次,由于检索出了5个客户。
外键
外键为某个表中的一列,它包含另外一个表的主键值,定义了两个表之间的关系。可伸缩性
: 可以适应不断增长的工做量而不失败。关系型数据库比非关系型数据库的可伸缩性好。联结
: 联结是一种机制,用来在一条select语句中关联表,所以称之为联结。使用特殊的语法,能够链接多个表返回一组输出,联结在运行时关联表中正确的行。
联结的引入是为了解决 为了带来关系数据更大的可伸缩性而分解数据为多个表,可是带来的代价:数据分散存储到多个表,怎么用单条select语句检索出数据。
两个表: 供应商表vendors, 产品表 products
建立(等值)联结
固然也能够按照主键,外键关系联结多个表。可是出于性能的考虑,这种处理多是很是耗资源的。联接的表越多,性能降低越厉害。
select 嵌套语句实现的返回订购产品TNT2的客户列表的解决方法,可使用级联:
对比:
select * from customers where cust_id in (select cust_id from orders where order_num in (select order_num from orderitems where prod_id = 'TNT2'));
VS
使用不一样类型的联结
有两种方法,一种是使用嵌套,另外一种是使用自联接。
嵌套:
自联接(同一个表别名为p1,p2);
> 有时候,处理联结要比查理子查询快的多。
使用outer join
来指定联结的类型。而不是在where子句。
使用带汇集函数的链接
检索全部客户及每一个客户所下的订单数。
使用Union操做符将多条select语句组合成一个结果集,并将结果做为单个查询结果集返回。这些组合查询称为并
或复合查询compound query
有两种状况,须要使用组合查询:
1. 在单个查询中从不一样的表返回相似结构的数据;
Union
使用where:
使用union:
union 从查询结果集中自动去除了重复的。
MyISAM 支持全文本搜索
InnoDB 不支持全文本搜索
通配符和正则表达式的缺陷:
性能
通配符和正则表达式匹配一般要求MySQL尝试匹配表中全部行
(并且这些搜索极少使用表索引)。所以,因为被搜索行数不断增长,这些搜索可能很是耗时。
明确控制
使用通配符和正则表达式匹配,很难(并且并不老是能)明确地控制匹配什么和不匹配什么。
智能化的结果
通配符和正则表达式匹配并不是是智能化的选择结果。
一个特殊词的搜索将会返回包含该词的全部行,而不区分包含单个匹配的行和包含多个匹配的行。
为了进行全文本搜索,必须索引
被搜索的列,并且要随着数据的改变不断地从新索引。在对表列进行适当设计后,MySQL会自动进行全部的索引和从新索引。
在索引以后,select可与match()
和agianst()
一块儿使用以执行搜索。match()
指定被搜索的列,against()
指定要使用的搜索表达式。
建立表时启用全文本搜索。接受fulltext子句,给出被索引列的
CREATE TABLE productnotes( note_id int NOT NULL AUT_INCREMENT, note_text text NULL, FULLTEXT(note_text)
create table 接受 full text子句。
SELECT note_text FROM tb_name WHERE Match(note_text) Against(‘rabbit’)
全文搜索(compared to like and regexp) 一个重要部分就是对结果排序。具备较高优先级的列先返回(由于这些行极可能就是你真正想要的行):好比先返回第三个词rabbit的行,再返回第20个词rabbit的行。
一个对比:
like是按照出现顺序,先返回第20个词rabbit的行,再返回第三个词rabbit的行。
放宽所返回的全文本搜索结果的范围。
好比:
想找到全部提到anvils的注释,只有一个注释包含了词anvils,可是你还想找出可能与你的搜索有关的全部其余行,即便不包含词anvils.
在使用查询扩展时,mysql对数据和索引两遍扫描完成。利用查询扩展,能找出可能相关的结果,即便它们并不精确包含所查找的词。
首先,进行一个基本的全文本搜索,找出与搜索条件匹配的全部行;
其次,MySQL检查这些匹配行并选择全部有用的词。
再其次,MySQL再次进行全文本搜索们此次不只使用原来的条件,并且还使用全部有用的词。
以布尔方式,能够提供关于以下内容的细节:
表达式分组;
另一些内容
SELECT note_text FROM productontes WHERE Match(note_text) Against(‘heavy’ IN BOOLEAN MODE)
排除了任何包含rope*的行。
例子:
搜索匹配safe和combination。下降后者的等级。
插入行到数据库表。
能够
insert into customers ( cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email) values('Pep E. LaPew', '100 Main Streat', 'Los Angels', 'CA', '90046', 'USA', null, null );
安全的insert语句,在表名后的括号里明确地给出列名。
当插入多行数据时候,用单条insert语句处理多个插入比使用多条insert语句快。
还能够插入检索出的数据。insert select
:假如想从另外一个表中合并客户列表到你的customers表,不须要每次读取一行,而后再用insert插入,能够直接 insert select.
形式:
mysqlinsert into TableName(ColomnName1,...) select (ColomnName1,...) from AnotherTableName;
不要求列明匹配,使用的是列的位置。
mysqlupdate TABLENAME set ColomnName1 = NewValue, ColomnName2 = NewValue where ... (过滤条件)
若是上面例子,没有where过滤条件,就是更新全部行。
设置为null(if表定义容许为null)
mysqlupdate TABLENAME set ColomnName1 = Null, where ... (过滤条件)
mysqldelete from TABLENAME where ... (过滤条件)
若是上面例子,没有where过滤条件,就是删除全部行。
Note: delete 语句是从表中删除行,甚至是删除表中全部行。可是delete不删除表自己。
Note: 更快的删除,若是想从表中删除全部行,不要使用delete, 可以使用truncate table语句(完成相同功能,可是速度更快,其实是删除原来的表并从新建立一个表,而非逐行删除表的数据)。
mysqlCREATE TABLE customers ( cust_id int NOT NULL AUTO_INCREMENT, cust_name char(50) NOT NULL , cust_address char(50) NULL , cust_city char(50) NULL , cust_state char(5) NULL , cust_zip char(10) NULL , cust_country char(50) NULL , cust_contact char(50) NULL , cust_email char(255) NULL , PRIMARY KEY (cust_id) ) ENGINE=InnoDB;
主键只能使用不容许NULL值的列。容许NULL值的列不能做为惟一标识。
每一个表只容许一个AUTO_INCREMENT列,并且它必须被索引。
MySQL内部具备各自不一样的功能和特性的多种引擎,为不一样的任务选择正确的引擎能得到良好的功能和灵活性。
InnoDB 是一个可靠的事务处理引擎,它不支持全文本搜索;
Memory 在功能等同于MyISAM, 但因为数据存储在内存(而非磁盘)中,速度很快(特别适合于临时表);
MyISAM 是一个性能极高的引擎,它支持全文本搜索,但不支持事务处理。
更新表定义,alter table
.
mysqlalter table vendors add vend_phone char(20);
删除表,而非内容
mysqldrop table tableName;