MySQL 必知必会读书笔记 (1)

想更一进步的支持我,请扫描下方的二维码,你懂的~
图片描述mysql

基本术语

  • 数据库 database: 一个以某种有组织的方式存储的数据集合。理解数据库最简单的方法是想象成一个文件柜。
  • 表 table:某种特定类型数据的结构化清单。表能够保存顾客清单、产品目录或者其余信息清单。
    特定类型 表示存储在表中的数据是一种类型的数据或一个清单,功能专注。决不该该把两种类型的表混合在一块儿。
  • 模式 schema:关于数据库和表的布局及特性的信息。好比表存储什么样的数据,数据如何分解,各部分信息如何命名等等。
  • 列 column:表由列组成。列是表中的一个字段。全部表都是由一个或多个列组成的。
  • 行 row:表中的一个记录。
  • 主键 primary key:一列(或者一组列)其值可以惟一区分表中的每一个行
    表中任意列均可以做为主键,只要知足以下条件:

    • 任意两行都不具备相同的主键值
    • 每一行都必须有一个主键值(即不准是NULL)
  • SQL 结构化查询语言

mysql 命令行

进入

mysql

或者git

mysql -u username -p

而后输入密码正则表达式

use

建立库:算法

create database dbname;

删除库sql

drop database dbname;

选择数据库,使用use关键字;如数据库

use kvseg;

show

  • 显示可用的数据库列表
SHOW DATABASES

返回可用的数据库的一个列表。segmentfault

  • 显示一个数据库内的表的列表,使用
SHOW TABLES

clipboard.png

  • 显示表列
SHOW COLUMNS FROM customers

clipboard.png

导入导出

  • 从Linux系统导入
    先在mysql建立一个数据表,选择进去,而后导入外部数据库进入表。
create database dbname;
use dbname;
source dir

dir是.sql文件的路径。若是不清楚路径能够输入pwd指令查看当前路径安全

clipboard.png

  • 从mysql导出到系统
mysqldump -u root -p news > news.sql

检索数据

select语句

select 子句顺序svg

子句    说明                     
select    要返回的列或表达式        
from      从中检索数据的表          
where     行级过滤
group by  分组说明
having    组级过滤
order by  输出排序顺序
limit     要检索的行数

为了使用select检索表数据,必须至少给两条信息 -- 想选择什么(哪一列),以及从什么地方(数据库)选择函数

  • 检索单个列
    好比检索cust_name字段(列),若是没有明确排序查询结果,则获得未排序的数据。
select cust_name from customers;

clipboard.png

  • 检索多个列
    好比从customers 检索cust_id,cust_name两列;
select cust_id,cust_name from customers;

clipboard.png

  • 检索全部列
select * from products;
  • 检索不一样的行(去重)
select distinct vend_id from products;

clipboard.png

  • 限制结果
    select 返回匹配的全部行,也能够返回第一行或者前几行,可以使用LIMIT关键字
    好比返回很少于5行;
select prod_name from products limit 5;

好比从行5开始的5行

select prod_name from products limit 55;

clipboard.png


order by

排序检索数据
使用select语句的order by 子句,根据须要排序检索出数据。

  • 按单个列排序
select *
from products
order by 列名(keyword for sorting)

clipboard.png
order by 子句取一个或多个列的名字,据此对输出进行排序。

  • 按多个列排序

clipboard.png

按照多个列排序时,排序彻底按照所规定的顺序进行。换句话说,对于上述中的输出,仅仅在多个行具备相同的segk(第一关键字)值时才对按照randnum(第二关键字)排序。

  • 升序?降序?
    默认是升序,降序是DESC

clipboard.png

还能够实现按照第一个关键字降序,第二个关键字升序

clipboard.png
DESC只用到直接位于其前面的列明。若是想在多个列上进行降序排列,必须对每一个列指定DESC关键字。

IN A CONCLUSION: order by子句必须是select语句的最后一条子句。

where

op descriptions
= 等于
<> 不等于
!= 不等于
< / > 小于 / 大于
<= / >= 小于等于/ 大于等于
Between 在指定的两个值之间
is NULL 空值检查

  • 过滤数据
    使用where过滤数据:从大量数据中检索出根据搜索条件/过滤条件过滤出来的数据。
mysqlselect * from products
 where prod_price = 55;

clipboard.png

  • 过滤不匹配
mysqlselect * from products
 where prod_price <> 55;
  • 范围检测
mysqlselect * from products
 where prod_price between 30 and 60;

clipboard.png

  • 空值
mysqlselect * from products
 where prod_price is Null;
  • 多条件,组合 and / or
    > 组合where子句(使用操做符and/or):更高级的search criteria. MYsql 容许给出多个WHERE子句。 这些子句以两种方式使用:Not and In。

clipboard.png


计算次序问题: 使用圆括号明确的分组相应的操做符。
好比选择segk 为118 或者 120的行,而且随机数小于等于2;
由于sql对and进行优先级处理。

任什么时候候后使用具备and 和 or操做符的where子句,都应该使用圆括号明确的分组操做符,不要过度依赖默认的计算次序。使用圆括号来消除歧义。

  • IN操做符
    IN操做符用来指定范围。(等同于or)

clipboard.png

  • NOT操做符
    否认它以后所跟的任何条件

clipboard.png


like

正则表达式 regexp

在where 条件中使用REGEXP关键字。

  • 基本字符匹配
    检索列prod_name 包含文本1000的全部行:
    clipboard.png

  • 进行OR匹配
    至关于:或操做 “|”

clipboard.png

  • 匹配几个字符之一
    只想匹配特定的字符。 能够经过指定一组用[]括起来的字符来完成。
    clipboard.png
    [456]定义了一组字符,他的意思是匹配4或5或6. []是另外一种形式的OR语句。[456][4|5|6]的缩写。
  • 匹配范围
    [1-3] a-z都是合法的范围、
    clipboard.png
  • 匹配特殊字符
    正则表达式语言由特殊含义的特殊字符构成。

    . 在正则表达式中表示匹配任何一个字符

    好比匹配prod_name中包括on字符串的行:
    clipboard.png

    那如何匹配.,[],|,-

    为了匹配特殊字符,必须用\\为前导。 好比\\.表示查找·

  • 匹配字符类

    clipboard.png

  • 匹配多个实例

    clipboard.png

    clipboard.png

    再好比 匹配连在一块儿的4位数字:

    sticks? : s后的使s可选,由于匹配它前面紧跟的任何字符的0次或者1次出现。

    clipboard.png

    [:digit:]匹配任意数字,于是它为数字的一个集合。{4}确切地要求它前面的字符出现4次。
    因此[:digit:]{4}匹配连在一块儿的任意4位数字。
    clipboard.png

  • 定位符
    目前为止全部例子都是匹配一个串中任意为止的文本。为了匹配特定为止的文本,须要使用定位符。

    clipboard.png

    clipboard.png


concat

  • 拼接字段
    存储在数据库表中的数据通常不是应用程序所须要的格式。咱们须要直接从数据库中检索出转换、计算或格式化过的数据;而不是检索出数据,而后再在客户机应用程序或报告程序中从新格式化。

    计算字段(字段 = 列,不过数据库列通常称为列,而字段一般用于计算字段中)并不实际存在于数据库表中,计算字段是运行时在select语句内建立的。

    拼接 concatenate 将值联结到一块儿构成单个值
    在MySQL的select语句中,可以使用Concat()函数来拼接两个列。

    如建立由两列组成的标题:生成一个供应商报表,须要在供应商的名字中按照name(location)这样的格式列出供应商的位置。此报表须要单个值,而表中数据存储的两个列vend_namevend_country中。还须要用括号将vend_country括起来。

    clipboard.png

    新建立的列用AS赋一个别名

    clipboard.png

  • 去除空白
    Ltrim() RTrim() Trim()
  • 执行算术计算
    好比物品单单表存储物品的价格和数量,可是不须要存储每一个物品的总价格(用价格乘以数量便可)。 为打印发票,须要物品的总价格。即须要增长一列,根据已有的列计算出来。

clipboard.png

文本函数

left()  串左边字符
length() 串长度
locate() 找出串的一个子串
lower() 转为小写
ltrim() 去掉左边空格
right() 返回串右边字符
rtrim() 去掉串右边空格
soundex() 返回字符串soundex值
upper() 大写

将选择的文本转换成大写

select Upper(vend_name)
from vendors;

clipboard.png

Soundex()函数:将任何文本传转换为描述其语音表示的字母数字模式的算法。(语音匹配?对发音比较而不是对字幕比较)

clipboard.png

日期函数

日期和时间函数
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

clipboard.png

可是这样的where order_date = '2005-09-01'不可靠。由于order_date存储的数据类型是datatime. 这种类型存储日期及时间值。好比存储的order_date值为2005-09-01 11:30:05,则where order_date = '2005-09-01'就会匹配失败。

clipboard.png

因此最安全的方法是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;

clipboard.png
- 计数
使用count(*)对表中行的数目进行计数(whether null or not)

clipboard.png

clipboard.png

使用count(column)对特定列具备值的行进行计数,忽略null

clipboard.png

  • 求和
    使用sum()返回指定列值的和

clipboard.png

group

目前为止全部计算都是在表的全部数据或匹配特定的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 这个表
clipboard.png
主键是prod_id 产品id,每个产品都对应一个供应商ID,产品名,产品价格,以及简介。
若是咱们查看该产品表的供应商信息:
clipboard.png
若是想进一步获知每一个供应商提供多少种产品,就应该对供应商进行分组: 好比供应商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.
    clipboard.png
    若是想要统计出订单数目超过2的顾客id
    clipboard.png
    增长的having子句,过滤了count(*)>=2那些分组。

    wherehaving组合使用,能够进行更强功能的操做。 如:列出提供了2个以上,价格为10以上的产品的供应商:

    clipboard.png
    先用wehre子句过滤了全部价格至少为10的行,而后按照vend_id分组数据,having子句过滤计数为2或2以上的分组。

  • 分组和排序
    clipboard.png

子查询

能够涉及数据库多个表,检索数据的语句。

  • 子查询用作过滤 in
    订单存储在两个表(orders,orderitems)中。
    clipboard.png
    客户信息存储在customers表中
    clipboard.png

    若是须要列出订购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'));

    clipboard.png

  • 做为计算字段使用子查询
    若是须要显示customers表中每一个客户的订单总数。 这须要使用customers,orders两个表。
    clipboard.png
    使用select count(*) 对表中的行进行计数,并经过where 子句过滤行(经过过滤id)

    orders是一个计算字段,它是由圆括号中的子查询创建的。该子查询对检索出的每一个客户执行一次。在这个例子中,该子查询执行了5次,由于检索出了5个客户。


联接表(join)

外键 外键为某个表中的一列,它包含另外一个表的主键值,定义了两个表之间的关系。
可伸缩性: 可以适应不断增长的工做量而不失败。关系型数据库比非关系型数据库的可伸缩性好。
联结: 联结是一种机制,用来在一条select语句中关联表,所以称之为联结。使用特殊的语法,能够链接多个表返回一组输出,联结在运行时关联表中正确的行。
联结的引入是为了解决 为了带来关系数据更大的可伸缩性而分解数据为多个表,可是带来的代价:数据分散存储到多个表,怎么用单条select语句检索出数据。

两个表: 供应商表vendors, 产品表 products

clipboard.png

  • 建立(等值)联结

    clipboard.png
    固然也能够按照主键,外键关系联结多个表。可是出于性能的考虑,这种处理多是很是耗资源的。联接的表越多,性能降低越厉害。

    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

    clipboard.png

clipboard.png

  • 使用不一样类型的联结

    clipboard.png

    • 自联接
      > 查询product_id为DTNTR(products表)的供应商,这个供应商生产的其余物品(vendors表)

    有两种方法,一种是使用嵌套,另外一种是使用自联接。
    嵌套:
    clipboard.png
    自联接(同一个表别名为p1,p2);
    clipboard.png

    > 有时候,处理联结要比查理子查询快的多。

    • 外部联结
      联结包含了哪些在相关表中没有关联的行。这种类型的链接称为外部连接。
      内部链接:

    clipboard.png

    使用outer join来指定联结的类型。而不是在where子句。
    clipboard.png

  • 使用带汇集函数的链接
    检索全部客户及每一个客户所下的订单数。

clipboard.png

  • 使用联结和联结条件
    > 1. 注意所使用的联结类型。通常使用内部联结,可是使用外部联结也是有效的.
    > 2. 保证使用正确的联结条件,不然将返回不正确的数据。
    > 3. 应该老是提供联结条件,不然会得出笛卡尔积。
    > 4. 在一个联结中能够包含多个表,甚至对每一个联结能够采用不一样的联结类型。虽然这样作是合法的,通常也颇有用,但应该在一块儿测试他们以前,分别测试每一个联结。排除故障更简单。

组合查询

使用Union操做符将多条select语句组合成一个结果集,并将结果做为单个查询结果集返回。这些组合查询称为复合查询compound query

有两种状况,须要使用组合查询:
1. 在单个查询中从不一样的表返回相似结构的数据;

  1. 在单个表执行多个查询,按单个查询返回数据。
  • Union
    假如须要价格小于等于5的全部物品的信息,还想包括供应商1001,1002生产的全部物品(不考虑价格)

使用where:
clipboard.png
使用union:
clipboard.png

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’)

clipboard.png

全文搜索(compared to like and regexp) 一个重要部分就是对结果排序。具备较高优先级的列先返回(由于这些行极可能就是你真正想要的行):好比先返回第三个词rabbit的行,再返回第20个词rabbit的行。
一个对比:

clipboard.png
like是按照出现顺序,先返回第20个词rabbit的行,再返回第三个词rabbit的行。

查询扩展

放宽所返回的全文本搜索结果的范围。
好比:
想找到全部提到anvils的注释,只有一个注释包含了词anvils,可是你还想找出可能与你的搜索有关的全部其余行,即便不包含词anvils.

在使用查询扩展时,mysql对数据和索引两遍扫描完成。利用查询扩展,能找出可能相关的结果,即便它们并不精确包含所查找的词。

  • 首先,进行一个基本的全文本搜索,找出与搜索条件匹配的全部行;

  • 其次,MySQL检查这些匹配行并选择全部有用的词。

  • 再其次,MySQL再次进行全文本搜索们此次不只使用原来的条件,并且还使用全部有用的词。

clipboard.png

clipboard.png

clipboard.png

布尔文本搜索

以布尔方式,能够提供关于以下内容的细节:

  • 要匹配的词;
  • 要排斥的词(即便它包含其余指定的词,可是若是它包括了排斥的词,也不返回该行);
  • 排列提示(指定某些词比其余词更重要,更重要的词等级更高);
  • 表达式分组;

  • 另一些内容

SELECT note_text
 FROM productontes
 WHERE Match(note_text) Against(‘heavy’ IN BOOLEAN MODE)

clipboard.png

clipboard.png

排除了任何包含rope*的行。
例子:
clipboard.png

clipboard.png

clipboard.png

搜索匹配safe和combination。下降后者的等级。

Insert

插入行到数据库表。
能够

  • 插入完整的行
  • 插入行的一部分
  • 插入多行
  • 插入某些查询的结果
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;

不要求列明匹配,使用的是列的位置。


update

更新特定行

mysqlupdate TABLENAME
set ColomnName1 = NewValue,
ColomnName2 = NewValue
where ... (过滤条件)

更新全部行

若是上面例子,没有where过滤条件,就是更新全部行。


delete

删除某个列的值

设置为null(if表定义容许为null)

mysqlupdate TABLENAME
set ColomnName1 = Null,
where ... (过滤条件)

删除特定的行

mysqldelete from TABLENAME
where ... (过滤条件)

删除全部行

若是上面例子,没有where过滤条件,就是删除全部行。

Note: delete 语句是从表中删除行,甚至是删除表中全部行。可是delete不删除表自己。
Note: 更快的删除,若是想从表中删除全部行,不要使用delete, 可以使用truncate table语句(完成相同功能,可是速度更快,其实是删除原来的表并从新建立一个表,而非逐行删除表的数据)。


create

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

更新表定义,alter table.

mysqlalter table vendors
add vend_phone char(20);

drop

删除表,而非内容

mysqldrop table tableName;
相关文章
相关标签/搜索