MySQL实践-连接表-内连接(一)

说明

MySQL中的连接及其语法是MySQL中的重要部分,要理解连接,需要了解关系表中的一些基础知识。假设有一个包含产品目录信息的数据库表,其中每种类别的物品占一行,存储的消息包括产品描述和价格,以及生产该产品的供应商信息。现在假如有多个产品是由同一供应商生产的,那么这些供应商的信息应该存储在何处?如果和产品信息放在一起,那么必然会出现同一张表中重复存储了相同的供应商信息(不同产品),此外,如果供应商信息改变,那么每次改动都要改动多次,还要保证重复数据的一致性,这些都是不利于我们组织管理数据的地方,因此针对数据分表就是个比较好的方案。
在上面的例子中,我们可以建立两个表,产品信息表(products)和供应商信息表(vendors),vendors表中存储所有供应商的信息,每个供应商占一行,并且每个供应商具有唯一的ID作为主键,products表中存储所有产品的信息,此外对于每个产品只保存其对应的供应商ID作为外键,需要查询对应产品的供应商信息时通过产品信息表中的供应商ID去供应商表中来查询,这样做的好处是不会重复存储供应商信息,节省了空间和时间,另外供应商信息变动时无需更改产品信息表,也由于没有重复数据,在使用维护上更加方便。
上面的例子同时也说明了在关系型数据库中,合理的设计和组织数据存储形式可以大大地增加数据库的可扩展性,这也是关系型数据库的优势之一。
针对上面的例子,products表数据如下:

mysql> SELECT * FROM products;
+---------+---------+----------------+------------+----------------------------------------------------------------+
| prod_id | vend_id | prod_name      | prod_price | prod_desc                                                      |
+---------+---------+----------------+------------+----------------------------------------------------------------+
| ANV01   |    1001 | .5 ton anvil   |       5.99 | .5 ton anvil, black, complete with handy hook                  |
| ANV02   |    1001 | 1 ton anvil    |       9.99 | 1 ton anvil, black, complete with handy hook and carrying case |
| ANV03   |    1001 | 2 ton anvil    |      14.99 | 2 ton anvil, black, complete with handy hook and carrying case |
| DTNTR   |    1003 | Detonator      |      13.00 | Detonator (plunger powered), fuses not included                |
| FB      |    1003 | Bird seed      |      10.00 | Large bag (suitable for road runners)                          |
| FC      |    1003 | Carrots        |       2.50 | Carrots (rabbit hunting season only)                           |
| FU1     |    1002 | Fuses          |       3.42 | 1 dozen, extra long                                            |
| JP1000  |    1005 | JetPack 1000   |      35.00 | JetPack 1000, intended for single use                          |
| JP2000  |    1005 | JetPack 2000   |      55.00 | JetPack 2000, multi-use                                        |
| OL1     |    1002 | Oil can        |       8.99 | Oil can, red                                                   |
| SAFE    |    1003 | Safe           |      50.00 | Safe with combination lock                                     |
| SLING   |    1003 | Sling          |       4.49 | Sling, one size fits all                                       |
| TNT1    |    1003 | TNT (1 stick)  |       2.50 | TNT, red, single stick                                         |
| TNT2    |    1003 | TNT (5 sticks) |      10.00 | TNT, red, pack of 10 sticks                                    |
+---------+---------+----------------+------------+----------------------------------------------------------------+
14 rows in set (0.00 sec)

vendors表设计如下:

mysql> SELECT * FROM vendors;
+---------+----------------+-----------------+-------------+------------+----------+--------------+
| vend_id | vend_name      | vend_address    | vend_city   | vend_state | vend_zip | vend_country |
+---------+----------------+-----------------+-------------+------------+----------+--------------+
|    1001 | Anvils R Us    | 123 Main Street | Southfield  | MI         | 48075    | USA          |
|    1002 | LT Supplies    | 500 Park Street | Anytown     | OH         | 44333    | USA          |
|    1003 | ACME           | 555 High Street | Los Angeles | CA         | 90046    | USA          |
|    1004 | Furball Inc.   | 1000 5th Avenue | New York    | NY         | 11111    | USA          |
|    1005 | Jet Set        | 42 Galaxy Road  | London      | NULL       | N16 6PS  | England      |
|    1006 | Jouets Et Ours | 1 Rue Amusement | Paris       | NULL       | 45678    | France       |
+---------+----------------+-----------------+-------------+------------+----------+--------------+
6 rows in set (0.00 sec)

内连接

内连接也称为等值连接,它连接要查询的两个表,基于两个表之间的相等测试进行检索,创建内部连接十分简单,如下:
SELECT vend_name, prod_name, prod_price FROM vendors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name,prod_name
上面的语句连接了两张表,并使用WHERE子句来确保正确连接,在这里WHERE用来指示MySQL匹配vendors表中的vend_idproducts中的vend_id,也就是说,在连接表时,MySQL实际上会将第一个表中的每一行与第二个表中的每一行进行匹配,满足匹配条件的会作为连接结果,如果不指定WHERE子句来限制匹配条件,连接的结果会是两张表行数的乘积,也叫作笛卡尔积,往往不是我们想要的结果。
对于内连接,MySQL提供了专用的语法,如下:

mysql> SELECT vend_name, prod_name, prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;
+-------------+----------------+------------+
| vend_name   | prod_name      | prod_price |
+-------------+----------------+------------+
| Anvils R Us | .5 ton anvil   |       5.99 |
| Anvils R Us | 1 ton anvil    |       9.99 |
| Anvils R Us | 2 ton anvil    |      14.99 |
| LT Supplies | Fuses          |       3.42 |
| LT Supplies | Oil can        |       8.99 |
| ACME        | Detonator      |      13.00 |
| ACME        | Bird seed      |      10.00 |
| ACME        | Carrots        |       2.50 |
| ACME        | Safe           |      50.00 |
| ACME        | Sling          |       4.49 |
| ACME        | TNT (1 stick)  |       2.50 |
| ACME        | TNT (5 sticks) |      10.00 |
| Jet Set     | JetPack 1000   |      35.00 |
| Jet Set     | JetPack 2000   |      55.00 |
+-------------+----------------+------------+
14 rows in set (0.00 sec)

执行结果与上面使用WHERE的一样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值