1、外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。通过外键查找:
SELECT vend_name, prod_name, prid_price FROM vendors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name;
在引用的列可能出现二义性,必须使用完全限定列名。
如果没有用WHERE子句进行条件过滤则返回的结果是笛卡尔积,即两个表行的乘积。
2、上条的语句所用的联结是等值联结,它基于两个表之间的相等测试,这种联结也成为内部联结。对于这种联结可以使用不同的语法:
SELECT vend_name, prod_name, prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;
ANSI SQL规范首先INNER JOIN语法。
3、SQL对一条SELECT语句中可以联结的表的数目没有限制,创建联结规则基本相同。
但MySQL在运行时关联指定的每个表以处理联结,这种处理可能很耗费资源,因此不要联结不必要的表,联结的表越多性能下降越厉害。
4、自联结
加入想查询ID为DTNTR的物品相同生产厂家的其他物品,可以采用子查询的方式:
SELECT prod_id, prod_name FROM products
WHERE vend_id = ( SELECT vend_id FROM products WHERE prod_id ='DTNTR');
也可以采用自联结的方式:
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';
在查询中需要的两个表实际上是相同的表,但对products的引用具有二义性,所以使用表别名。
自联结通常作为外部语句用来替代从相同表中检索数据时使用的子查询语句。虽然结果相同,但处理联结比处理子查询快很多。
5、外部联结
联结包含了那些在相关表中没有关联行的行:
SELECT customers.cust_id, orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id = orders.cust_id;
在使用OUTER JOIN 时必须使用RIGHT或LEFT关键字指定包括没有关联行的表。LEFT指OUTER JOIN左侧的表,以此类推。
6、组合查询UNION
组合数条SQL查询:
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);
组合时列的类型必须兼容,不必完全相同,但是可以隐式的转换。
组合结果时会自动去掉重复的行,如果不想去掉重复行需使用UNION ALL代替UNION。
对组合结果进行排序,只能使用一条ORDER BY子句,它必须出现在最后一条SELECT语句之后。
7、全文搜索
使用MATCH()和AGAINST(),MATCH()指定要搜索的列,AGAINST()指定匹配的文本。
搜索的列必须建立搜索索引,创建表时用FULLTEXT()包含列。
只有MyISAM引擎支持全文搜索,InnoDB不支持,并且汉语不具有词分隔符,所以不能返回全文搜索的结果,所以工作中应该很少用到。
8、插入
插入完整行,不指定列名插入
INSERT INTO customers
VALUES(value1,
value2,
......
valuen);
指定列名插入
INSERT INTO 表名(列名1,
列名2,
......,
列名n)
VALUES(value1,
valuen);
如果表的定义允许,则可以在INSERT操作中省略某些列,省略的列必须满足以下条件之一:
INSERT语句很耗时,而且可能降低等待处理的SELECT语句的性能。如果数据检索是最重要的,则可以通过在INSERT和INTO之间添加关键字LOW_PRIORITY,指示MySQL降低INSERT语句的优先级。同样适用于UPDATE和DELETE语句。
可以一条语句插入多行:
INSERT INTO 表名(列名1,
列名2,
......,
列名n)
VALUES(value1,
valuen),
(value1,
valuen);
9、插入检索出的数据 INSERT SELECT
INSERT INTO 表名(列名1,
......,
列名n)
SELECT 列名1,
......,
列名n
FROM 另一个表名;
10、更新数据UPDATE
UPDATE 表名
SET 列名1=value1,
列名2=value2
WHERE 过滤条件;
如果用UPDATE语句更新多行,并且在更新这些行中的一行出现错误时,则整个UPDATE操作被取消;如果想即使发生错误也继续进行更新使用:UPDATE IGNORE 表名。
11、删除数据
DELETE FROM 表名
WHERE 过滤条件;
如果想从表中删除所有行,不要使用DELETE。可使用TRUNCATE TABLE语句,它完成相同的工作,但速度更快。TRUNCATE TABLE实际是删除原来的表并重新创建一个表,而不是逐行删除表中的数据。
在使用UPDATE或DELETE语句前,应该先用SELECT带相同的WHERE子句进行测试,保证它过滤的是正确的记录。
12、创建表
CREATE TABLE customers (
cust_id int(11) NOT NULL AUTO_INCREMENT,
cust_name char(50) NOT NULL,
cust_address char(50) DEFAULT NULL,
cust_city char(50) DEFAULT NULL,
cust_state char(5) DEFAULT NULL,
cust_zip char(10) DEFAULT NULL,
cust_country char(50) DEFAULT NULL,
cust_contact char(50) DEFAULT NULL,
cust_email char(255) DEFAULT NULL,
PRIMARY KEY (`cust_id`)
) ENGINE=InnoDB AUTO_INCREMENT=10006 DEFAULT CHARSET=latin1
创建的表名必须不存在,如果存在将报错。如果仅想在一个表不存在时创建它,应该使用CREATE TABLE IF NOT EXISTS 表名。
是否可以为NULL设置,NULL为默认值。主键只能使用不允许为NULL的列。
13、AUTO_INCREMENT
每个表只能有一个AUTO_INCREMENT列,而且它必须被索引。
如果一个列被指定为AUTO_INCREMENT,它还可以被赋予特殊值,在INSERT语句中指定值,并且保证它是唯一的即可。该值将被用来替代自动生成的值,后续的增量将开始使用该手工插入的值。
使用last_insert_id()函数可以返回最后一个AUTO_INCREMENT值。
14、通过DEFAUTL关键字可以指定列的默认值。MySQL不允许使用函数作为默认值,它只支持常量。
建议使用默认值而不是NULL。
15、引擎类型
DBMS使用内部引擎管理和处理数据。MySQL具有多种引擎:
引擎可以混用,不同的表使用不同的引擎。但是外键不能夸引擎。
16、更新表ALERT TABLE
添加一个列:ALTER TABLE vendors ADD vend_phone CHAR(20);
删除一个列:ALTER TABLE vendors DROP COLUMN vend_phone;
定义外键:ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_oders
FOREIGN KEY (order_num) REFERENCES orders(order_num);
17、删除表DROP TABLE 表名
18、重命名表 RENAME TABLE 原表名 TO 新表名;