该代码不仅更短,而且也更容易理解和高效。我们不是执行两个查询,而是执行一个查询。
尽管该问题听起来有些牵强,但是在实践中我们通常总结出所有的表应该在同一个数据库中,除非有非常迫不得已的理由。
问题 4:不使用关系
关系数据库不同于编程语言,它们不具有数组类型。相反,它们使用表之间的关系来创建对象之间的一到多结构,这与数组具有相同的效果。我在应用程序中 看到的一个问题是,工程师试图将数据库当作编程语言来使用,即通过使用具有逗号分隔的标识符的文本字符串来创建数组。请看下面的模式。
清单 10. Bad.sql
以下为引用的内容:DROP TABLE IF EXISTS files; CREATE TABLE files ( id MEDIUMINT, name TEXT, path TEXT ); DROP TABLE IF EXISTS users; INSERT INTO files VALUES ( 1, 'test1.jpg', 'media/test1.jpg' ); |
系统中的一个用户可以具有多个文件。在编程语言中,应该使用数组来表示与一个用户相关联的文件。在本 例中,程序员选择创建一个 files 字段,其中包含一个由逗号分隔的文件 id 列表。要得到一个特定用户的所有文件的列表,程序员必须首先从用户表中读取行,然后解析文件的文本,并为每个文件运行一个单独的 SELECT 语句。该代码如下所示。
清单 11. Get.php
以下为引用的内容:<?php require_once("DB.php"); function get_files( $name ) $res = $db->query( "SELECT files FROM users WHERE login=?", $rows = array(); foreach( split( ',',$files ) as $file ) return $rows; $files = get_files( 'jack' ); var_dump( $files ); |
该技术很慢,难以维护,且没有很好地利用数据库。惟一的解决方案是重新架构模式,以将其转换回到传统的关系形式,如下所示。
清单 12. Good.sql
以下为引用的内容:DROP TABLE IF EXISTS files; CREATE TABLE files ( id MEDIUMINT, user_id MEDIUMINT, name TEXT, path TEXT ); DROP TABLE IF EXISTS users; INSERT INTO users VALUES ( 1, 'jack', 'pass' ); |
延伸阅读:
在MySQL数据库中如何来复位根用户的密码
MySQL数据库出错代码列表
怎样在MySQL数据库中导出整个数据库
深入MySQL数据库的索引
MySQL数据库的启动与终止