1.表中的任何列都可以作为主键, 只要它满足以下条件:
任意两行都不具有相同的主键值;
每一行都必须具有一个主键值( 主键列不允许NULL值) ;
主键列中的值不允许修改或更新;
主键值不能重用( 如果某行从表中删除, 它的主键不能赋给以后的新行)
2.MySQL的要求:任意两行都不具有相同的主键值;
每个行都必须具有一个主键值(主键列不允许NULL值)。
3.tips:除MySQL强制实施的规则外,应该坚持的
几个普遍认可的最好习惯为:
不更新主键列中的值;
不重用主键列的值;
不在主键列中使用可能会更改的值。(例如,如果使用一个
名字作为主键以标识某个供应商,当该供应商合并和更改其
名字时,必须更改这个主键。)
第二章
1.MySQL选项和参数 如果仅输入mysql, 可能会出现一个错误
消息。因为可能需要安全证书,或者是因为MySQL没有运行
在本地或默认端口上。 mysql接受你可以(和可能需要)使用
的一组命令行参数。例如,为了指定用户登录名ben,应该使
用mysql -u ben。为了给出用户名、主机名、端口和口令,
应该使用mysql -u ben -p -h myserver -P 9999。
完整的命令行选项和参数列表可用mysql --help获得。
2.命令输入在mysql>之后;
命令用;或\g结束,换句话说,仅按Enter不执行命令;
输入help或\h获得帮助,也可以输入更多的文本获得特定命令的
帮助(如,输入help select获得使用SELECT语句的帮助);
输入quit或exit退出命令行实用程序。
第三章
1.必须先使用USE打开数据库,才能读取其中的数据。
2.SHOW COLUMNS 要 求 给 出 一 个 表 名 ( 这 个 例 子 中 的 FROM
customers),它对每个字段返回一行,行中包含字段名、数据
类型、是否允许NULL、键信息、默认值以及其他信息(如字段cust_id
的auto_increment)。
什么是自动增量? 某些表列需要唯一值。例如,订单编号、
雇员ID或(如上面例子中所示的)顾客ID。在每个行添加到表
中时, MySQL可以自动地为每个行分配下一个可用编号,不
用在添加一行时手动分配唯一值(这样做必须记住最后一次使
用的值)。这个功能就是所谓的自动增量。
3.SHOW STATUS,用于显示广泛的服务器状态信息;
SHOW CREATE DATABASE和SHOW CREATE TABLE,分别用来显示创
建特定数据库或表的MySQL语句;
SHOW GRANTS,用来显示授予用户(所有用户或特定用户)的安
全权限;
SHOW ERRORS和SHOW WARNINGS, 用来显示服务器错误或警告消息。
第四章 检索数据
1.要想从一个表中检索多个列,使用相同的SELECT语句。唯一的不同
是必须在SELECT关键字后给出多个列名,列名之间必须以逗号分隔。
2.mysql命令行用;
3.在选择多个列时,一定要在列名之间加上逗号,但
最后一个列名后不加。如果在最后一个列名后加了逗号,将出
现错误。
4.如果给定一个通配符( *),则返回表中所有列
5.SELECT DISTINCT vend_id告诉MySQL只返回不同(唯一)的
vend_id行,因此只返回4行.不能部分使用DISTINCT DISTINCT关键字应用于所有列而
不仅是前置它的列。
6.此语句使用SELECT语句检索单个列。 LIMIT 5指示MySQL返回
不多于5行.LIMIT 5, 5指示MySQL返回从行5开始的5行。
7.SELECT products.prod_name FROM products;
第五章,排序
1.SELECT prod_name
FROM products
ORDER BY prod_name;
2.SELECT prod_id,prod_price,prod_name FROM products
ORDER BY prod_price,prod_name DESC;
DESC表示降序,ASC是升序
3.如何区分大小写和排序顺序是数据库管理员设定规则
4.在给出ORDER BY子句时,应该保证它
位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY
之后。使用子句的次序不对将产生错误消息。
第六章 过滤数据
1.SELECT prod_name,prod_price
FROM products
WHERE prod_price=2.50
2.在同时使用ORDER BY和WHERE子句时,应
该让ORDER BY位于WHERE之后, 否则将会产生错误
3.SELECT prod_name,prod_price
FROM products
WHERE prod_price BETWEEN 5 AND 10;
4.SELECT prod_name
FROM products
WHERE prod_price IS NULL;
第七章 数据过滤
1.AND在计算次序中优先级更高。
2.SELECT prod_name,prod_price
FROM products
WHERE vend_id NOT IN (1002,1003)
ORDER BY prod_name;
3.MySQL 支 持 使 用 NOT 对 IN 、 BETWEEN 和
EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件
取反有很大的差别。
第八章 用通配符进行过滤
1.通配符,搜索模式,在搜索子句中用通配符必须使用LIKE操作符
2.SELECT prod_id,prod_name
FROM products
WHERE prod_name LIKE 'jet%';
%表示任何字符出现的任意次数。
3.tips:尾空格可能会干扰通配符匹配。例如,在保存词
anvil 时 , 如 果 它 后 面 有 一 个 或 多 个 空 格 , 则 子 句 WHERE
prod_name LIKE '%anvil'将不会匹配它们,因为在最后的l
后有多余的字符。解决这个问题的一个简单的办法是在搜索模
式最后附加一个%。
虽然似乎%通配符可以匹配任何东西,但有一个例
外,即NULL。即使是WHERE prod_name LIKE '%'也不能匹配
用值NULL作为产品名的行
4.与%能匹配0个字符不一样, _总是匹配一个字符,不能多也不能少。
5.tips:不要过度使用通配符。如果其他操作符能达到相同的目的,应该
使用其他操作符。
在确实需要使用通配符时,除非绝对有必要,否则不要把它们用
在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起
来是最慢的。
仔细注意通配符的位置。如果放错地方,可能不会返回想要的数
第九章 用正则表达式进行搜索
1.SELECT prod_name
FROM products
WHERE prod_name REGEXP'1000'
ORDER BY prod_name;
2.LIKE是匹配整个列,REGEXP匹配列值,为在搜索子句中使用通配符,必须使用LIKE操作符。 LIKE指示MySQL,
后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
3.MySQL正则表达式匹配后不区分大小写。区分大小写可以用BINARY关键字,如WHERE prod_name REGEXP BINARY 'JetPack.000'
4.匹配特定的字符用[].
5.否定字符集合用^.
6.正则表达式匹配列值,只要列值中含有就可以,LIKE则是匹配整个列形式。
7..是匹配任意字符,匹配特殊字符用\为前导。、|[].
8.\f换页,\n换行,\r回车,\t制表,\v纵向制表。
9.找出你自己经常使用的数字,所有字母字符或所有数字字母字符的匹配。预定义的字符类。
[:alnum:]任意字母和数字
[:alpha:]任意字符
[:blank:]空格和制表[\t]
[:cntrl:]ASCII控制字符 0到31和127
[:digit:]任意数字
[:graph:]与[:print:]相同,但不包括空格
[:lower:]任意小写
[:print:]任意可打印字符
[:punct:]既不是alnum也不是cntrl的字符
[:space:]包括空格在内的空白字符,同[\f\n\r\t\v]
[:upper:]
[:xdigit:]任意十六进制数字
10.匹配多个实例
*0个或多个匹配
+1个或多个
?0个或1个
{n}指定数目的匹配
{n,}不少于指定数目的匹配
{n,m}匹配数目的范围
11.^文本的开始 $文本的结尾 [[:<:]]词的开始 [[:>:]]词的结尾
SELECT 'hello' REGEXP '[0-9]'返回0
第十章 创建计算字段
1.存储在表中的数据都不是应用程序所需要的。
我们需要直接从数据库中检索出转换、计算或格式化过的数据;而不是
检索出数据,然后再在客户机应用程序或报告程序中重新格式化。
这就是计算字段发挥作用的所在了。与前面各章介绍过的列不同,
计算字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句
内创建的。数据库知道SELECT语句中哪些列是实际的
表列,哪些列是计算字段。从客户机(如应用程序)的角度来看,计算
字段的数据是以与其他列的数据相同的方式返回的。
2.tips:多数DBMS使用+或||来实现拼接,
MySQL则使用Concat()函数来实现。当把SQL语句转换成
MySQL语句时一定要把这个区别铭记在心
3.SELECT Concat(vend_name,'(',vend_country,')')
FROM vendors
ORDER BY vend_name;
4.SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')')
FROM vendors
ORDER BY vend_name;
Rtrim去掉右边所有空格,Ltrim去掉左边所有空格
5.使用别名
SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')')AS
vent_title
FROM vendors
ORDER BY vend_name;
6.计算字段
SELECT prod_id,
quatity,
item_price,
quatity*item_price AS expanded_price
FROM orderotems
WHERE order_num=2005;
第十一章 用数据处理函数
1.常用文本处理函数
Left()返回左边字符,Length(),Locate()找出串的一个子串,Lower(),LTrim(),Right(),Rtrim(),Soundex()返回串的soundex值,SubString()返回子串的字符,Upper()
2.SELECT cust_name,cust_contact
FROM customers
WHERE Soundex(cust_contact)=Soundex('Y Lie');
3.日期和时间处理函数
AddDate()天,周,AddTime()时,分,CurDate(),CurTime(),Date()日期时间的日期部分,DateDiff()日期之差,Date_Add()高度灵活的日期运算函数,Date_Format()返回格式化日期或者时间串,Day(),DayOfWeek(),Hour(),Minute(),Month(),Now(),Second(),Time(),Year()。
4.数值处理函数
abs(),cos(),exp(),mod(),pi(),rand()随机数,sin(),sqrt(),tan()
第十二章 汇总数据
1.聚集函数 运行在行组上,计算和返回单个值的函数。
2.AVG()平均值COUNT()行数 MAX()MIN()SUM()
3.SELECT AVG(prod_price)AS avg_price
FROM products;
4.确定特定列的平均值
AVG()忽略NULL的行
SELECT AVG(prod_price) AS avg_price
FROM products
WHERE vend_id =1003;
5.COUNT()
COUNT()包含null,COUNT(column)忽略null
SELECT COUNT() AS num_cust
FROM customers;
6.MAX()在用于文本数据时,如果数
据按相应的列排序,则MAX()返回最后一行。???
7.SELECT SUM(item_pricequantity)AS total_price
FROM orderitems
WHERE order_num=2005;
8.distinct只考虑不同的
SELECT AVG(DISTICT prod_price)AS avg_price
FROM products
WHERE vend_id =1003;
9tips:
如果指定列名,则DISTINCT只能用于COUNT()。DISTINCT
不能用于COUNT(),因此不允许使用COUNT( DISTINCT),
否则会产生错误。类似地, DISTINCT必须使用列名,不能用
于计算或表达式。
第十三章 分组数据
1.SELECT vend_id, COUNT() AS num_prods
FROM products
GROUP BY vend_id;
GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套,
为数据分组提供更细致的控制。
如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上
进行汇总。换句话说,在建立分组时,指定的所有列都一起计算
(所以不能从个别的列取回数据)。
GROUP BY子句中列出的每个列都必须是检索列或有效的表达式
(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在
GROUP BY子句中指定相同的表达式。不能使用别名。
除聚集计算语句外, SELECT语句中的每个列都必须在GROUP BY子
句中给出。
如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列
中有多行NULL值,它们将分为一组。
GROUP BY子句必须出现在WHERE子句之后, ORDER BY子句之前。
使用有 WITH ROLLUP 子句的 GROUP BY 语句时,不能再使用 ORDER语句对结果集进行排序,如果对返回的结果顺序不满意,需要应用程序获得结果后在程序中进行排序
2.WHERE 过滤行,HAVING过滤分组
SELECT cust_id,COUNT()AS orders
FROM orders
GROUP BY cust_id
HAVING count()>=2;
这里有另一种理解方法,WHERE在数据
分组前进行过滤, HAVING在数据分组后进行过滤。这是一个重
要的区别, WHERE排除的行不包括在分组中。这可能会改变计
算值,从而影响HAVING子句中基于这些值过滤掉的分组。
3.SELECT vend_id,COUNT()AS num_prods
FROM products
WHERE prod_price>=10
GROUP BY vend_id
HAVING COUNT()>=2;
4.如果用了having 就要用group by。
SELECT order_num,SUM(quatityitem_price)AS ordertotal
FROM orderitems
GROUP BY order_num
HAVING SUM(quatity*item_price)>=50
ORDER BY ordertotal;
5.SELECT 是
WHERE 否
GROUP BY 按组计算聚集使用
HAVING 否 ORDER BY
LIMIT 否
第14章 使用子查询
1.SQL
SELECT cust_id
FROM orders
WHERE order_num IN(SELECT order_num
FROM orderitems
WHERE prod_id='TNT2');
2.SELECT cust_name,cust_contact
FROM customers
WHERE cust_id IN(SELECT cust_id
FROM orders
WHERE order_num IN(SELECT order_num
FROM orderitems
WHERE prod_id='TNT2'));
3.列必须匹配:
在WHERE子句中使用子查询(如这里所示),应
该保证SELECT语句具有与WHERE子句中相同数目的列。通常,
子查询将返回单个列并且与单个列匹配,但如果需要也可以
使用多个列。
4.SELECT cust_name,
cust_state,
(SELECT COUNT(*)
FROM orders
WHERE order.cust_id=customers.cust_id)AS orders
FROM customers
ORDER BY cust_name;
第十五章 联结表
1.外键为某个表中的一列,它包含另一个表
的主键值,定义了两个表之间的关系。
2.在一条SELECT语句中联结几个表时,相应的关系是
在运行中构造的。在数据库表的定义中不存在能指示MySQL如何对表进
行联结的东西。你必须自己做这件事情。在联结两个表时,你实际上做
的是将第一个表中的每一行与第二个表中的每一行配对。 WHERE子句作为
过滤条件,它只包含那些匹配给定条件(这里是联结条件)的行。
3.由没有联结条件的表关系返回
的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘
以第二个表中的行数。
4.SELECT vend_name,prod_name,prod_price
FROM vendors INNER JOIN products
ON vendors.vend_id=products.vend_id;
5.ANSI SQL规范首选INNER JOIN语法。此外,
尽管使用WHERE子句定义联结的确比较简单,但是使用明确的
联结语法能够确保不会忘记联结条件,有时候这样做也能影响
性能
SELECT cust_name,cust_contact
FROM customers
WHERE cust_id IN(SELECT cust_id
FROM orders
WHERE order_num IN(SELECT order_num
FROM orderitems
WHERE prod_id='TNT2'));
SELECT cust_name,cust_contact
FROM customers,orders,orderitems
WHERE customers.cust_id=orders.cust_id
AND orderitems.order_num=order.order_num
ADN prod_id='TNT2';
第十六章 创建高级联结
1.SELECT p1.prod_id,p1.prod_name
FROM products AS p1,products AS p2
WHERE p1.vend_id=p2.vend_id
AND p2.prod_id='DTNTR';
自联结通常作为外部语句用来替代
从相同表中检索数据时使用的子查询语句。虽然最终的结果是
相同的,但有时候处理联结远比处理子查询快得多。应该试一
下两种方法,以确定哪一种的性能更好。
2.自然联结
SELECT c.*o.order_num,o.order_date,
oi.prood_id,oi.quatity,OI.item_price
FROM customers AS c,orders AS o,orderitems AS oi
WHERE c.cust_id=o.cust_id
AND oi.order_num=o.order_num
AND prod_id='FB';
通配符只对第一个表使用。所有其他列明确列
出,所以没有重复的列被检索出来。
3.SELECT customer.cust_id,orders.order_num
FROM customers INNER JOIN orders
ON customers.cust_id=orders.cust_id;
4.SELECT customer.cust_id,orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id;
这条SELECT语句使用了关
键字OUTER JOIN来指定联结的类型(而不是在WHERE子句中指
定)。但是,与内部联结关联两个表中的行不同的是,外部联结还包括没
有关联行的行。在使用OUTER JOIN语法时,必须使用RIGHT或LEFT关键字
指定包括其所有行的表( RIGHT指出的是OUTER JOIN右边的表,而LEFT
指出的是OUTER JOIN左边的表)。上面的例子使用LEFT OUTER JOIN从FROM
子句的左边表( customers表)中选择所有行。???
5.SELECT customers.cust_name,
customers.cust_id,
COUNT(orders.order_num)AS num_ord
FROM customers INNER JOIN orders
ON customers.cust_id=orders.cust_id
GROUP BY custmers.cust_id;
6.SELECT customers.cust_name,
customers.cust_id,
COUNT(orders.order_num)AS num_ord
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id=orders.cust_id
GROUP BY customers.cust_id:
第十七章 组合查询
1.使用UNION
SELECT vend_id,prod_id,prod_price
FROM products
WHERE prod_price<=5
UNION
SELECT vend_id,prod_id,prod_price
FROM products
WHERE vend_id IN(1001,1002);
TIPS:UNION可能比使用WHERE子句更为复杂。
但对于更复杂的过滤条件,或者从多个表(而不是单个表)中检索数据
的情形,使用UNION可能会使处理更简单。
- UNION规则
必须由两条或两条以上的SELECT语句组成,语句之间用关
键字UNION分隔(因此,如果组合4条SELECT语句,将要使用3个
UNION关键字)。
UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过
分析各个列不需要以相同的次序列出)。
列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以
隐含地转换的类型(例如,不同的数值类型或不同的日期类型)。
如果遵守了这些基本规则或限制,则可以将并用于任何数据检索任务。
UNION可以去除重复的行,想返回所有匹配行,使用UNION ALL 而不是UNION,在使用UNION组合查询的时候,只能使用一条ORDER BY,必须出现在最后一条SELECT语句之后 不能用多条
第十八章,全文本搜索
1.MySQL
支持几种基本的数据库引擎。并非所有的引擎都支持本书所描
述的全文本搜索。两个最常使用的引擎为MyISAM和InnoDB,
前者支持全文本搜索,而后者不支持。这就是为什么虽然本书
中 创 建 的 多 数 样 例 表 使 用 InnoDB , 而 有 一 个 样 例 表
( productnotes表)却使用MyISAM的原因。