MySQL

范式、联结、子查询、正则表达式和基于全文本的搜素、存储过程、游标、触发器、表约束


范式详解:https://www.zhihu.com/question/24696366

范式(NF):数据表的表结构所符合的某种设计标准的级别。1NF、2NF、3NF、BCNF、4NF、5NF。解决数据冗余过大,插入异常,删除异常,修改异常问题。

第一范式(1NF):符合1NF的关系中的每个属性都不可再分。1NF是所有关系数据库的最基本要求。

第二范式:2NF在1NF的基础之上,消除了非主属性对于码的部分函数依赖。

第三范式:3NF在2NF的基础之上,消除了非主属性对于码的传递函数依赖。

BCNF:在3NF的基础上,消除主属性对于码的部分与传递函数依赖。


函数依赖:完全函数依赖、部分函数依赖、传递函数依赖。

    码:K为表中的一个或一组属性,若除K之外的所有属性都 完全依赖于K,K为候选码,简称码。(假如当K确定的情况下,该表除K之外的所有属性的值也随之确定,那么K就是码)。一张表中可以有超过一个码。(实际应用中为了方便,通常选择其中一个码作为主码)

非主属性:包含在任何一个码中的属性为主属性。

模式分解:无损连接性(信息不失真(不增减信息))和函数依赖性(不破坏属性间的依赖关系)。


数据库:以某种有组织的方式存储的数据集合

表:用来存储某种特定类型的数据

列:表中的一个字段,每列都有相应的数据类型

数据类型:所容许的数据的类型,限制(或容许)该列中存储的数据

行(元组):表中的一个记录

主键:一列(或一组列),能够唯一区别表中每一行。
主键要求:1、任意两行都不具有相同的主键;     2、每一行都必须具有一个主键值(主键列不允许null值)。    
主键习惯:1、不跟新主键列中的值;     2、不重用主键列的值;     3、不在主键列中使用可能会更改的值。

外键:外键是某个表的一列,它 包含另一个表的主键值,定义了两个表之间的关系。
设计多对多映射关系,使用中间表。

自动增量:某些表列需要唯一值。在每行添加到表中时,mysql可以自动地为每一行分配下一个可用编号,不用在添加一行时手动分配唯一值。这个功能就是自动增量


mysql不区分大小写,表名和列名用小写,关键字用大写


SELECT
DISTINCT:应用于所有列而不仅是前置它的列。除非指定的列都不同,否则所有都将被检索出来
LIMIT:限制返回的最大行值。LIMIT 5—返回不多于5行。LIMIT 5,5—从行5开始的5行,第一个数为开始位置,第二个数为要检索的行数
SELECT DISTINCT vend_id FROM products LIMIT 5,5;

子句:sql语句由子句构成。一个子句通常由一个关键字和所提供的数据组成。


排序检索数据:
ORDER BY:按字母顺序排序数据。通常ORDER BY子句中使用的列将是为显示所选择的列。但实际上并不一定要这样,用非检索的列排序数据时完全合法的

按多个列排序:只要指定列名,列名之间用逗号分开即可


DESC:按降序排序,DESC只应用到直接位于其前面的列名。如果想在多个列上进行降序排序,必须对每个列指定DESC关键字

ASC:升序(默认)


SELECT prod_price FROM products ORDER BY prod_price DESC LIMIT 1;


过滤数据:WHERE
WHERE和ORDER BY同时出现时,ORDER BY位于WHERE后面


操作符:用来联结或改变WHERE子句中子句的关键字。

AND,OR,AND的优先级大于OR,使用圆括号。
IN:用来指定条件范围,范围中的每个条件都可以进行匹配,由逗号分隔,IN完成与OR相同的功能
NOT:否定它之后所跟的任何条件


通配符:用来匹配值的一部分的特殊字符。在搜索子句中使用通配符,必须使用LIKE操作符。

%:表示匹配任何字符出现任意次数(也能匹配0个字符),但不能匹配NULL;
_(下划线):匹配任意字符,但只匹配单个字符。


正则表达式:REGEXP
mysql中的正则表达式匹配不区分大小写,为区分大小写,用BINARY关键字, REGEXP BINARY

.:匹配任意一个字符
|:匹配其中之一
[]:匹配特定字符[]中的一个字符,[123],[^123]表示匹配除这些字符外的任何字符,[1-9]、[a-z]表示范围
为了匹配特殊字符,必须用\\为前导,转义。
元字符:具有特殊含义的字符。
\\f:换页
\\n:换行
\\r:回车
\\t:制表
\\v:纵向制表





例:REGEXP '\\([0-9] sticks?\\)'.     \\(匹配(,[0-9]匹配任意数字,sticks匹配stick和sticks(s后的?使s可选,因为?匹配它前面的任意字符的0次或1次出现,\\)匹配))


^:在集合中[]用它来否定该集合,否则,用来指串的开始处

LIKE匹配整个串,REGEXP匹配子串。利用定位符,通过用^开始每个表达式,用&结束每个表达式,可以使REGEXP的作用与LIKE一样

计算字段、拼接字段:使用Concat()函数拼接。使用RTrim()函数删除数据右侧多余的空格,LTrim()去掉左边的空格,Trim()去掉左右两边的空格


别名AS:一个字段或值的替换名。


SELECT Concat(RTrim(vend_name),'(',RTrim(vend_country),')') AS vend_title FROM vendors ORDER BY vend_name;


AS vend_title指示SQL创建一个包含指定计算的名为vend_title的计算字段,任何客户机应用都可以按名引用这个列

SELECT prod_id,quantity,item_price,quantity*itme_price AS expanded_price FROM orderitems WHERE order_num=20005;







汇总数据:
聚集函数:运行在行组上,计算和返回单个值的函数



分组数据:分组是在SELECT语句的GROUP BY子句中建立的
使用WITH ROLLUP关键字,得到每个分组以及每个分组汇总级别(针对每个分组)的值

HAVING支持所有WHERE操作符,WHERE过滤行,HAVING过滤分组。WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。WHERE排除的行不包括在分组中。


SELECT vend_id,COUNT(*) AS num_prods FROM products WHERE prod_price >= 10 GROUP BY vend_id HAVING COUNT(*) >= 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'));



SELECT cust_name,
       cust_state,
       (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders
       FROM customers
       ORDER BY cust_name;


相关子查询:设计外部查询的子查询。只要列名可能有多义性,就使用(表名和列名由一个句点分隔)


联结
在一条SELECT语句中联结几个表时,相应的关系是在运行中构造的。在联结两个表时,实际上做的是将第一个表中的每一行与第二个表中的每一行配对。WHERE子句作为过滤条件,它只包含哪些匹配给定条件(这里的联结条件)的行。应该保证所有联结都有WHERE子句
笛卡儿积:没有联结条件(WHERE子句)的表关系返回的结果为笛卡儿积。检索出的行的数目将是第一个表中的行数乘以第二个表中的行数

等值联结

SELECT vend_name,prod_name,prod_price
FROM vendors,products 
WHERE vendors.vend_id = products.vend_id
ORDER BY vend_name,prod_name;

内部联结
SELECT vend_name,prod_name,prod_price 
FROM vendors INNER JOIN products
ON vendors.vend_id = products.vend_id;


联结多个表
SELECT prod_name,vend_name,prod_price,quantity
FROM orderitems,products,vendors
WHERE products.vend_id = vendors.vend_id
  AND orderitems.prod_id = products.prod_id

  AND order_num = 20005;


表别名:缩短SQL语句;允许在单条SELECT语句中多次使用相同的表。customers AS c


自联结、自然联结、外部联结(联结包含了那些在相关表中没有关联行的行)
SELECT customer.cust_id, orders.order_num
FROM customers INNER JOIN orders

ON customer.cust_id = orders.cust_id;


包括没有订单的客户:

SELECT customer.cust_id, orders.order_num
FROM customers LEFT OUTER JOIN orders
ON customers.cust_id = orders.cust_id;

在使用OUTER JOIN 语法时,必须使用LEFT或RIGHT关键字指定包含其所有行的表。

使用带聚集函数的联结

组合查询

UNION:1、UNION必须由两条或两条以上的SELECT语句组成,语句之间用关键词UNION分隔;
     2、UNION中的每个查询必须包含相同的列、表达式或聚集函数(不过各个列不需要以相同的次序列出);
     3、列数据类型必须兼容:类型不必完全相同,但必须是DBMS可以隐含地转换的类型(例如不同的数值类型或不同的日期类型)。

UNION从查询结果集中自动去除了重复的行(它的行为与单条SELECT语句中使用多个WHERE子句条件一样),这是UNION的默认行为,使用UNION ALL可以返回所有匹配行。
在用UNION组合查询时,只能使用一条ORDER BY子句,必须出现在最后一条SELECT语句之后。用来排序所有SELECT语句返回的所有结果。

使用UNION极大地简化复杂的WHERE子句,简化从多个表中检索数据的工作。


全文本搜索

mysql支持几种基本的数据库引擎,最常用的是MyISAM和InnoDB,前者支持全文本搜索,后者不支持。

为了进行全文本搜索,必须索引被搜索的列,而且要随着数据的改变不断地重新索引。可以索引单个列,也可以指定多个列。可以在创建表时指定FULLTEXT,或者在稍后指定(在这种情况下所有已有数据必须立即索引)。在索引之后,使用Match()和Against()执行全文本搜索,Match()指定被搜索的列,Against()指定要使用的搜索表达式。

传递给Match()的值必须与FULLTEXT()定义中的相同。如果指定多个列,则必须列出它们(而且次序正确)。搜索不区分大小写。

全文本搜索的一个重要部分是对结果排序。具有较高等级的行先返回


查询扩展(放宽所返回的全文本搜索结果的范围)

步骤:1、首先进行一次全文本搜索,找出与搜索条件匹配的所有行;
     2、mysql检查这些匹配行并选择所有有用的词(mysql如何断定什么有用,什么无用)
     3、mysql再次进行全文本搜索,不仅使用原来的条件,而且还使用所有有用的词。

SELECT note_text 
FROM productnotes
WHERE Match(note_text) Against('anvils' WITH QUERY EXPANSION);

布尔文本搜索(提供内容细节):即使没有FULLTEXT索引也可以使用

     1、要匹配的词;
     2、要排斥的词;
     3、排列提示(等级);
     4、表达式分组;
     5、另外一些内容。

SELECT note_text 
FROM productnotes
WHERE Match(note_text) Against('heavy' IN BOOLEAN MODE );

匹配包含heavy但不包含任意以rope开始的词的行:

SELECT note_text 
FROM productnotes
WHERE Match(note_text) Against('heavy -rope*' IN BOOLEAN MODE );



全文本搜索的重要说明


INSERT
INSERT语句一般不会产生输出
不提供列名时,对每个列必须提供一个值。当有自动增量的列时,用NULL值。提供列名时,VALUES以其指定的次序匹配指定的列名,不一定按各个列出现在实际表中的次序,即使表结构改变,仍能够正常工作。

插入检索出的数据:INSERT SELECT



UPDATE(WHERE子句的使用
SET命令用来将新值赋给被更新的列。
在更新行中的一行或多行时出现错误,整个UPDATE操作被取消(错误发生前更新的所有行被恢复到它们原来的值)。为了即使是发生错误,也继续进行更新,使用IGNORE关键字。UPDATE IGNORE table_name...

DELETE(WHERE子句
TRUNCATE TABLE语句删除所有行

mysql没有撤销(undo)按钮


表的创建:

AUTO_INCREMENT,每个表只允许一个AUTO_INCREMENT列,而且它必须被索引

DEFAULT 默认值,默认值不支持函数,只支持常量,使用默认值而不是NULL值


mysql具有多种引擎。它打包多个引擎,这些引擎都隐藏在MySQL服务器内部,全都能执行CREATE TABLE和SELECT等命令。不同的引擎具有各自不同的功能和特性,为不同的任务选择正确的引擎能获得良好的功能和灵活性。

1、默认引擎为MyISAM,一个性能极高的引擎,它支持全文本搜素,但不支持事务处理;
2、InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索;
3、MEMORY在功能上等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适合于临时表)。

外键不能跨引擎,使用一个引擎的表不能引用不同引擎的表的外键

ALTER TABLE(更改表结构

ALTER TABLE vendors ADD vend_phone CHAR(20);
ALTER TABLE vendors DROP COLUMN vend_phone;

ALTER TABLE用于定义外键
ALTER TABLE orderitems 
ADD CONSTRAINT fk_orderitems_orders
FOREIGN KEY (order_num) REFERENCES orders(order_num);

DROP TANLE customers;

RENAME TABLE customers2 TO customers;


视图:只包含使用时动态检索数据的查询。作为视图,不包含表中应该有的任何列或数据,它包含的是一个SQL查询。


使用视图:

1、视图用CREATE VIEW语句创建;
2、使用SHOW CREATE VIEW viewname;查看创建视图的语句;
3、用DROP删除视图,语法为DROP VIEW viewname;
4、更新视图时,可以先用DROP再用CREATE,也可直接用CREATE OR REPLACE VIEW。

使用视图重新格式化检索出的数据、使用视图过滤不想要的数据


存储过程:为以后的使用而保存的一条或多条MySQL语句的集合。简单、安全、高性能。类似于函数

1、通过把处理封装在容易使用的单元中,简化复杂的操作;
2、由于不要求反复建立一系列处理步骤,保证了数据的完整性;
3、简化对变动的管理;
4、提高性能,使用存储过程比使用单独的SQL语句要快;
5、存在一些职能用在单个请求中的MySQL元素和特性,存储过程可以使用它们来编写功能更强更灵活的代码


执行存储过程:

CALL productpricing(@pricelow,@pricehigh,@priceaverage);


创建存储过程:

CREATE PROCEDURE productpricing()
BEGIN 
     SELECT Avg(prod_price) AS priceaverage
     FROM products;

END;

删除存储过程:DROP PROCEDURE productpricing;


CREATE PROCEDURE productpricing(
     OUT pl DECIMAL(8,2),
     OUT ph DECIMAL(8,2),
     OUT pa DECIMAL(8,2)
)
BEGIN
     SELECT Min(prod_price)
     INTO pl
     FROM products;
     SELECT Max(prod_price)
     INTO ph
     FROM products;
     SELECT Avg(prod_price)
     INTO pa
     FROM products;
END;

IN(传递给存储过程)、OUT(从存储过程传出)和INOUT(对存储过程传入和传出)。存储过程的代码位于BEGIN和END语句内,然后保存到相应的变量。

存储过程的参数允许的数据类型与表中使用的数据类型相同。记录集不是允许的类型,因此不能通过一个参数返回多个行和列。

所有MySQL变量都必须以@开始。

SELECT @priceaverage;
 
CREATE PROCEDURE ordertotal(
     IN onumber INT,
     OUT ototal DECIMAL(8,2)
)
BEGIN
     SELECT Sum(item_price*quantity)
     FROM orderitems
     WHERE order_num = onumber;
     INTO ototal;
END;


CALL ordertotal(20005,@total);

SELECT @total;

CREATE PROCEDURE ordertotal(
     IN onumber INT,
     IN taxable BOOLEAN,
     OUT ototal DECINAL(8,2)
)COMMENT 'Obtain order total,optionally adding tax'
BEGIN 
     --Declare variable for total
     DECLARE total DECIMAL(8,2);
     --Declare tax percentage
     DECLARE taxrate INT DEFAULT 6;

     --Get the order total
     SELECT Sum(item_price*quantity)
     FROM orderitems
     WHERE order_num = onumber
     INTO total;

     --Is this taxable?
     IF taxable THEN
     --Yes,so add taxrate to the total
     SELECT total+(total/100*taxrate) INTO total;
     END IF;

     --And finally,save to out variable
     SELECT total ITNO ototal;
END;

检查存储过程,显示创建一个存储过程的CREATE语句,SHOW CREATE PROCEDURE ordertotal;

SHOW PROCEDURE STATUS 列出所有存储过程,如何时、由谁创建等信息。为限制其输出,可使用LIKE指定过滤模式。

游标:一个存储在MySQL服务器上的数据库查询,是被SELECT语句检索出来的结果集。在存储了游标之后,应用程序可以根据需要滚动或浏览其中的数据。MySQL游标只能用于存储过程(或者函数)


创建游标:

CREATE PROCEDURE processorders()
BEGIN
     DECLARE ordernumbers CURSOR
     FOR
     SELECT order_num FROM orders;
END;

打开游标:

OPEN ordernumbers;

在处理OPEN语句时执行查询,存储检索出的数据以供浏览和滚动。

游标处理完后,关闭游标:

CLOSE ordernumbers;

CLOSE释放游标使用的所有内部内存和资源,因此在每个游标不再需要时都应该关闭。

当游标被打开后,可以使用FETCH语句分别访问它的每一行。FETCH指定检索什么数据(所需的列),检索出来的数据存储在什么地方。它还向前移动游标中的内部行指针,使下一条FETCH语句检索下一行(不重复读取同一行)。


CREATE PROCEDURE processorders()
BEGIN 
     --Declare local variables
     DECLARE o INT;

     --Declare the cursor
     DECLARE ordernumbers CURSOR
     FOR 
     SELECT order_num FROM orders;
     
     --Open the cursor
     OPEN ordernumbers;

     --Get order number
     FETCH ordernumbers INTO o; //检索单个行

     --Close the cursor
     CLOSE ordernumbers;
END;


CREATE PROCEDURE processorders()
BEGIN 
     --Declare local variables
     DECLARE done BOOLEAN DEFAULT 0;
     DECLARE o INT;

     --Declare the cursor
     DECLARE ordernumbers CURSOR
     FOR 
     SELECT order_num FROM orders;

     --Declare continue handler
     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; //条件出现时被执行的代码
     
     --Open the cursor
     OPEN ordernumbers;

     --Loop through all rows
     REPEAT

          --Get order number
          FETCH ordernumbers INTO o; 

     --End of loop
     UNTIL done END REPEAT;  //反复执行直到done为真

     --Close the cursor
     CLOSE ordernumbers;
END;



CREATE PROCEDURE processorders()
BEGIN 
     --Declare local variables
     DECLARE done BOOLEAN DEFAULT 0;
     DECLARE o INT;
     DECLARE t DECIMAL(8,2);

     --Declare the cursor
     DECLARE ordernumbers CURSOR
     FOR 
     SELECT order_num FROM orders;

     --Declare continue handler
     DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; //条件出现时被执行的代码

     --Create a table to store the results
     CREATE TABLE IF NOT EXISTS ordertotals
          (order_num INT, total DECIMAL(8,2));
     
     --Open the cursor
     OPEN ordernumbers;

     --Loop through all rows
     REPEAT

          --Get order number
          FETCH ordernumbers INTO o; 

          --Get the total for this order
          CALL ordertotal(o, 1, t);

          --Insert order and total into ordertotals
          INSERT INTO ordertotals(order_num, total)
          VALUES(o, t);

     --End of loop
     UNTIL done END REPEAT;  //反复执行直到done为真

     --Close the cursor
     CLOSE ordernumbers;
END;

触发器:MySQL响应以下任何语句而自动执行的一条MySQL语句(或位于BEGIN和END语句之间的一组语句):DELETE、INSERT、UPDATE.


创建触发器:1、唯一的触发器名;2、触发器关联的表;3、触发器应该响应的活动(DELETE、INSERT、UPDATE);4、触发器何时执行(处理之前或之后)。


CREATE TRIGGER newproduct AFTER INSERT ON products FOR EACH ROW SELECT 'Product added';


只有表支持触发器,视图不支持。

每个表每个事件每次只允许一个触发器。因此,每个表最多支持6个触发器(每条INSERT、UPDATE、DELETE之前和之后)。单一触发器不能与多个事件或多个表关联。


删除触发器:DROP TRIGGER newproduct;


INSERT触发器:1、在INSERT触发器代码内,可引用一个名为NEW的虚拟表,访问被插入的行;2、在BEFORE INSERT触发器中,NEW中的值也可以被更新(允许更改被插入的值);3、对于AUTO_INCREMENT列,NEW在INSERT执行之前包含0,在INSERT执行之后包含新的自动生成值。


通常BEFORE用于数据验证和净化(保证插入表中的数据确实是需要的数据)


事务处理:用来维护数据库的完整性,它保证成批的MySQL操作要么完全执行,要么完全不执行。
并非所有的引擎都支持事务处理。MyISAM和InnoDB,前者不支持,后者支持。


事务:一组SQL语句;
回退:撤销指定SQL语句的过程;
提交:将未存储的SQL语句结果写入数据库表;
保留点:事务处理中设置的临时占位符,你可以对它发布回退(与回退整个事务处理不同)。

事务处理用来管理INSERT、UPDATE、DELETE语句,不能回退SELECT语句,不能回退CREATE或DROP操作。事务处理块中可以使用这两条语句,但如果执行回退,它们不会被撤销。


SELECT * FROM ordertotals;
START TRANSACTION;
DELETE FROM ordertotals;
SELECT * FROM ordertotals;
ROLLBACK;
SELECT * FROM ordertotals;

在事务处理块中,提交不会隐含地进行,使用COMMIT语句。


START TRANSACTION;
DELETE FROM orderitems WHERE order_num = 20010;
DELETE FROM orders WHERE order_num = 20010;
COMMIT;

回退部分事务处理,必须能在事务处理块中合适的位置放置占位符

SAVEPOINT delete1;

ROLLBACK TO delete1;

保留点在事务处理完成(执行一条ROLLBACK或COMMIT)后自动释放


默认MySQL行为是自动提交所有更改。SET autocommit = 0;

autocommit标志是针对每个连接而不是服务器的




########################
# Create customers table
########################
CREATE 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;

#########################
# Create orderitems table
#########################
CREATE TABLE orderitems
(
  order_num  int          NOT NULL ,
  order_item int          NOT NULL ,
  prod_id    char(10)     NOT NULL ,
  quantity   int          NOT NULL ,
  item_price decimal(8,2) NOT NULL ,
  PRIMARY KEY (order_num, order_item)
) ENGINE=InnoDB;


#####################
# Create orders table
#####################
CREATE TABLE orders
(
  order_num  int      NOT NULL AUTO_INCREMENT,
  order_date datetime NOT NULL ,
  cust_id    int      NOT NULL ,
  PRIMARY KEY (order_num)
) ENGINE=InnoDB;

#######################
# Create products table
#######################
CREATE TABLE products
(
  prod_id    char(10)      NOT NULL,
  vend_id    int           NOT NULL ,
  prod_name  char(255)     NOT NULL ,
  prod_price decimal(8,2)  NOT NULL ,
  prod_desc  text          NULL ,
  PRIMARY KEY(prod_id)
) ENGINE=InnoDB;

######################
# Create vendors table
######################
CREATE TABLE vendors
(
  vend_id      int      NOT NULL AUTO_INCREMENT,
  vend_name    char(50) NOT NULL ,
  vend_address char(50) NULL ,
  vend_city    char(50) NULL ,
  vend_state   char(5)  NULL ,
  vend_zip     char(10) NULL ,
  vend_country char(50) NULL ,
  PRIMARY KEY (vend_id)
) ENGINE=InnoDB;

###########################
# Create productnotes table
###########################
CREATE TABLE productnotes
(
  note_id    int           NOT NULL AUTO_INCREMENT,
  prod_id    char(10)      NOT NULL,
  note_date datetime       NOT NULL,
  note_text  text          NULL ,
  PRIMARY KEY(note_id),
  FULLTEXT(note_text)
) ENGINE=MyISAM;


#####################
# Define foreign keys
#####################
ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_orders FOREIGN KEY (order_num) REFERENCES orders (order_num);
ALTER TABLE orderitems ADD CONSTRAINT fk_orderitems_products FOREIGN KEY (prod_id) REFERENCES products (prod_id);
ALTER TABLE orders ADD CONSTRAINT fk_orders_customers FOREIGN KEY (cust_id) REFERENCES customers (cust_id);
ALTER TABLE products ADD CONSTRAINT fk_products_vendors FOREIGN KEY (vend_id) REFERENCES vendors (vend_id);
########################################
# MySQL Crash Course
# http://www.forta.com/books/0672327120/
# Example table population scripts
########################################


##########################
# Populate customers table
##########################
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(10001, 'Coyote Inc.', '200 Maple Lane', 'Detroit', 'MI', '44444', 'USA', 'Y Lee', 'ylee@coyote.com');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES(10002, 'Mouse House', '333 Fromage Lane', 'Columbus', 'OH', '43333', 'USA', 'Jerry Mouse');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(10003, 'Wascals', '1 Sunny Place', 'Muncie', 'IN', '42222', 'USA', 'Jim Jones', 'rabbit@wascally.com');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact, cust_email)
VALUES(10004, 'Yosemite Place', '829 Riverside Drive', 'Phoenix', 'AZ', '88888', 'USA', 'Y Sam', 'sam@yosemite.com');
INSERT INTO customers(cust_id, cust_name, cust_address, cust_city, cust_state, cust_zip, cust_country, cust_contact)
VALUES(10005, 'E Fudd', '4545 53rd Street', 'Chicago', 'IL', '54545', 'USA', 'E Fudd');


########################
# Populate vendors table
########################
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1001,'Anvils R Us','123 Main Street','Southfield','MI','48075', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1002,'LT Supplies','500 Park Street','Anytown','OH','44333', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1003,'ACME','555 High Street','Los Angeles','CA','90046', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1004,'Furball Inc.','1000 5th Avenue','New York','NY','11111', 'USA');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1005,'Jet Set','42 Galaxy Road','London', NULL,'N16 6PS', 'England');
INSERT INTO vendors(vend_id, vend_name, vend_address, vend_city, vend_state, vend_zip, vend_country)
VALUES(1006,'Jouets Et Ours','1 Rue Amusement','Paris', NULL,'45678', 'France');


#########################
# Populate products table
#########################
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('ANV01', 1001, '.5 ton anvil', 5.99, '.5 ton anvil, black, complete with handy hook');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('ANV02', 1001, '1 ton anvil', 9.99, '1 ton anvil, black, complete with handy hook and carrying case');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('ANV03', 1001, '2 ton anvil', 14.99, '2 ton anvil, black, complete with handy hook and carrying case');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('OL1', 1002, 'Oil can', 8.99, 'Oil can, red');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('FU1', 1002, 'Fuses', 3.42, '1 dozen, extra long');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('SLING', 1003, 'Sling', 4.49, 'Sling, one size fits all');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('TNT1', 1003, 'TNT (1 stick)', 2.50, 'TNT, red, single stick');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('TNT2', 1003, 'TNT (5 sticks)', 10, 'TNT, red, pack of 10 sticks');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('FB', 1003, 'Bird seed', 10, 'Large bag (suitable for road runners)');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('FC', 1003, 'Carrots', 2.50, 'Carrots (rabbit hunting season only)');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('SAFE', 1003, 'Safe', 50, 'Safe with combination lock');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('DTNTR', 1003, 'Detonator', 13, 'Detonator (plunger powered), fuses not included');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('JP1000', 1005, 'JetPack 1000', 35, 'JetPack 1000, intended for single use');
INSERT INTO products(prod_id, vend_id, prod_name, prod_price, prod_desc)
VALUES('JP2000', 1005, 'JetPack 2000', 55, 'JetPack 2000, multi-use');



#######################
# Populate orders table
#######################
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20005, '2005-09-01', 10001);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20006, '2005-09-12', 10003);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20007, '2005-09-30', 10004);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20008, '2005-10-03', 10005);
INSERT INTO orders(order_num, order_date, cust_id)
VALUES(20009, '2005-10-08', 10001);


###########################
# Populate orderitems table
###########################
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 1, 'ANV01', 10, 5.99);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 2, 'ANV02', 3, 9.99);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 3, 'TNT2', 5, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20005, 4, 'FB', 1, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20006, 1, 'JP2000', 1, 55);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20007, 1, 'TNT2', 100, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20008, 1, 'FC', 50, 2.50);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 1, 'FB', 1, 10);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 2, 'OL1', 1, 8.99);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 3, 'SLING', 1, 4.49);
INSERT INTO orderitems(order_num, order_item, prod_id, quantity, item_price)
VALUES(20009, 4, 'ANV03', 1, 14.99);

#############################
# Populate productnotes table
#############################
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(101, 'TNT2', '2005-08-17',
'Customer complaint:
Sticks not individually wrapped, too easy to mistakenly detonate all at once.
Recommend individual wrapping.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(102, 'OL1', '2005-08-18',
'Can shipped full, refills not available.
Need to order new can if refill needed.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(103, 'SAFE', '2005-08-18',
'Safe is combination locked, combination not provided with safe.
This is rarely a problem as safes are typically blown up or dropped by customers.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(104, 'FC', '2005-08-19',
'Quantity varies, sold by the sack load.
All guaranteed to be bright and orange, and suitable for use as rabbit bait.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(105, 'TNT2', '2005-08-20',
'Included fuses are short and have been known to detonate too quickly for some customers.
Longer fuses are available (item FU1) and should be recommended.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(106, 'TNT2', '2005-08-22',
'Matches not included, recommend purchase of matches or detonator (item DTNTR).'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(107, 'SAFE', '2005-08-23',
'Please note that no returns will be accepted if safe opened using explosives.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(108, 'ANV01', '2005-08-25',
'Multiple customer returns, anvils failing to drop fast enough or falling backwards on purchaser. Recommend that customer considers using heavier anvils.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(109, 'ANV03', '2005-09-01',
'Item is extremely heavy. Designed for dropping, not recommended for use with slings, ropes, pulleys, or tightropes.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(110, 'FC', '2005-09-01',
'Customer complaint: rabbit has been able to detect trap, food apparently less effective now.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(111, 'SLING', '2005-09-02',
'Shipped unassembled, requires common tools (including oversized hammer).'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(112, 'SAFE', '2005-09-02',
'Customer complaint:
Circular hole in safe floor can apparently be easily cut with handsaw.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(113, 'ANV01', '2005-09-05',
'Customer complaint:
Not heavy enough to generate flying stars around head of victim. If being purchased for dropping, recommend ANV02 or ANV03 instead.'
);
INSERT INTO productnotes(note_id, prod_id, note_date, note_text)
VALUES(114, 'SAFE', '2005-09-07',
'Call from individual trapped in safe plummeting to the ground, suggests an escape hatch be added.
Comment forwarded to vendor.'
);








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值