MySQL中的外鍵約束之PHP篇
一、利用外鍵約束更新MySQL中的數據
現在,最流行的開源關系型數據庫管理系統非MySQL莫屬,而MySQL又支持多個存儲引擎,其中默認的也是速度較快的存儲引擎為MyISAM,對許多讀者來說,在開發自己數據庫驅動的web應用程序之前,可能已經使用了它很長一段時間了。
然而,有時候我們的項目可能需要額外的特性,例如需要處理外鍵約束,這時我們就需要用到其它類型的MySQL存儲引擎。在這種情況下,InnoDB表將 非常適合我們的要求,盡管在性能方面可能比MyISAM表要稍遜一籌。大家知道,使用InnoDB表外鍵約束主要優點之一就是,它使我們可以在數據庫級別 處理和維護多個表之間的關系,而無需將此任務推給與這些表打交道的應用程序的某些模塊或者程序庫。
當然,前面的幾篇文章中,我們已經就IndoDB表的外鍵約束做過相應介紹,但是那里都是通過手工方式來操作外鍵約束的。在本文中,我們將說明如何在更新和刪除父表中的數據時,如何通過腳本語言來觸發相應子表的級聯更新和刪除操作。
這里,我們博客應用程序的數據層由兩個表構成,在前面的示例中,對這些表的操作,都是通過手工鍵入SQL命令完成的,現在,我們將介紹如何使用PHP程 序設計語言來完成這些工作。之所以選擇PHP,是因為它目前MySQL最常見的搭配語言,下面我們以PHP 5為例來說明如何外鍵約束操作兩個InnoDB表。 通過閱讀本文,您將更加真切地體會到外鍵約束的特性。
現在,我們開始見證PHP 5和外鍵約束結合在一起所帶來的威力吧!
二、以級聯方式更新和刪除數據庫中的數據
古人云,溫故而知新,那么先讓我們來回顧一下前面學過的內容吧。之前,我們介紹過如何運用外鍵約束級聯更新和刪除存放博客文章評論的InnoDB表中的數據。如果您尚未閱讀前面的文章也不要緊,下面我們簡單回顧這些內容。
這里是我們的示例中用到的兩個表的定義,如下所示:
DROP TABLE IF EXISTS `test`.`blogs`;CREATE TABLE `test`.`blogs` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`title` TEXT,
`content` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `test`.`comments`;
CREATE TABLE `test`.`comments` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`blog_id` INT(10) UNSIGNED DEFAULT NULL,
`comment` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `blog_ind` (`blog_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
上面的代碼定義了兩個表,需要注意一下第二個,因為它為“blog_id”字段規定了一個約束,所以當post表中的數據被更新和刪除時,將觸發相應的級聯操作。
為了幫您理解這一過程,我們可以在表中填上一些數據,這時可以通過SQL語句INSERT來完成,如下:
INSERT INTO blogs (id, title, content, author) VALUES (NULL,'Title of the first blog entry', 'Content of the first blog entry', 'IAN')INSERT INTO comments (id, blog_id, comment, author) VALUES (NULL, 1, 'Commenting first blog entry', 'Tom'), (NULL, 1, 'Commenting first blog entry', 'Rose')
現在,我們唯一的一條博客數據已經有了兩條評論數據,如果由于任何原因需要更新博客及其評論數據的話,可以通過下列命令完成:
UPDATE blogs SET id = 2, title = 'Title of the first blog entry', content = 'Content of the first blog entry', author = 'John Doe' WHERE id = 1這看起來非常簡單,但是,如果我說將博客數據連同相應的評論數據一同刪除會更加簡單,您能會相信嗎?如果不信的話,請看下面的SQL語句:
DELETE FROM blogs WHERE id = 2如您所見,這就是刪除指定博客及其評論所需的全部SQL代碼,這足以證明通過外鍵約束維護兩個InnoDB表的完整性到底有多么的方便。
迄今為止,我們已經簡單回顧之前所學的內容,接下來,我們將繼續探索這些表的約束的各種優點。 就像本文開頭部分介紹的那樣,我們將開始講解如何通過PHP 5內置的MySQL抽象類來生成對我們的示例表的級聯更新。
三、利用PHP 5以級聯方式更新數據庫
好了,現在開始詳細介紹如何使用流行的服務器端腳本語言PHP 5來以級聯方式更新我們的示例表。為此,我們需要編寫允許我們訪問上面定義的InnoDB表的代碼,就本例而言,我們使用PHP 5的MySQL抽象類來達此目的。下面給出具體的代碼:
class MySQL{
private $result = NULL;
private $link = NULL;
//連接到MySQL
public function __construct($host, $user, $password, $database)
{
if (FALSE === ($this->link = mysqli_connect($host, $user, $password, $database)))
{
throw new Exception('Error : ' . mysqli_connect_error());
}
}
//執行查詢
public function query($query)
{
if (is_string($query) AND empty($query) === FALSE)
{
if (FALSE === ($this->result = mysqli_query($this->link, $query)))
{
throw new Exception('Error performing query ' . $query . ' Error message :' .mysqli_error($this->link));
}
}
}
//從結果集返回數據
public function fetch()
{
if (FALSE === ($row = mysqli_fetch_object($this->result)))
{
mysqli_free_result($this->result);
return FALSE;
}
return $row;
}
//獲取插入ID
public function getInsertID()
{
return mysqli_insert_id($this->link);
}
//結果集中的行數
public function countRows()
{
if ($this->result !== NULL)
{
return mysqli_num_rows($this->result);
}
}
//關閉數據庫連接
function __destruct()
{
mysqli_close($this->link);
}
}
如上所示,上面定義的MySQL抽象類十分簡單,它提供了許多常用的方法,用于執行查詢、統計結果集行數以及獲取插入ID。需要格外注意的是,這個類內部使用了PHP擴展mysqli來跟MySQL打交道,所以整體看來是很容易理解的。
好了,我們已經定義了一個可以用于跟MySQL數據庫相交互的PHP 5類,現在我們要做的就是利用它的API對前面定義的InnoDB表執行級聯更新。
四、MySQL抽象類
現在,為了演示如何使用上述的MySQL類級聯更新前文中的數據表,我們需要重新定義那兩個表,以便使其只能執行這些更新的操作。這里是它們的定義,這兩個表將作為我們的示例博客應用程序的數據層:
DROP TABLE IF EXISTS `test`.`blogs`;CREATE TABLE `test`.`blogs` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`title` TEXT,
`content` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `test`.`comments`;
CREATE TABLE `test`.`comments` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`blog_id` INT(10) UNSIGNED DEFAULT NULL,
`comment` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `blog_ind` (`blog_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
如上所述,通過給最后一個表中的blog_id字段規定外鍵約束,我們已經把兩個表聯系在了一起,接下來讓我們使用前面定義的MySQL抽象類給它們填 入必要的數據。我們假設這個類被單獨放入一個名為mysqlclass.php文件中,下面的腳本將向blog表中插入單篇博客文章,并向 comments表中插入兩則評論:
require_once 'mysqlclass.php';$db = new MySQL('host', 'user', 'password', 'test');
//在blogs數據庫表中插入新數據
$db->query("INSERT INTO blogs (id, title, content, author) VALUES (NULL,'Title of the first blog entry', 'Content of the first blog entry', 'IAN')");
$insid = $db->getInsertID();
//在comments數據庫表中插入新評論
$db->query("INSERT INTO comments (id, blog_id, comment, author) VALUES (NULL, $insid, 'Commenting first blog entry', 'Tom'), (NULL, $insid, 'Commenting first blog entry', 'Rose')");
雖然我們的這個MySQL類能夠抽象地訪問數據庫,但是相應的SQL查詢還得手工編寫。同時,它正好可以使我們可以展示每當第一個表中的數據更新時,如何使用該類來更新與第一個數據表相關的評論。
執行該級聯更新操作的代碼片斷如下所示:
//更新blogs表中的數據(comments表中的有關數據將自動更新)$db->query("UPDATE blogs SET id = 2, title = 'Title of the first blog entry', content = 'Content of the first blog entry', author = 'John Doe' WHERE id = 1");
盡管另外添加了一個與上述InnoDB表打交道的抽象類,但是觸發級聯更新所需的SQL代碼仍然保持高度簡潔。這說明,各表之間的關系的完整性仍然是在數據庫級別進行維護的,而不是由PHP 5應用程序所維護的。
五、小結
到目前為止,我們詳細講解了如何通過PHP 5內置的抽象類使用外鍵約束來更新兩個InnoDB表中的數據。 我們希望本文能夠對您利用服務器端腳本使用外鍵約束時能夠有所啟發。在后面的文章中,我們將繼續探討外鍵約束有關的內容。
【IT168 文檔】在本文中,我們將學習如何通過PHP 5的一個基本抽象類使用外鍵約束來更新兩個InnoDB表的數據。 我們將通過具體示例來說明如何通過服務器端腳本語言來使用外鍵約束。
一、利用外鍵約束更新MySQL中的數據
現在,最流行的開源關系型數據庫管理系統非MySQL莫屬,而MySQL又支持多個存儲引擎,其中默認的也是速度較快的存儲引擎為MyISAM,對許多讀者來說,在開發自己數據庫驅動的web應用程序之前,可能已經使用了它很長一段時間了。
然而,有時候我們的項目可能需要額外的特性,例如需要處理外鍵約束,這時我們就需要用到其它類型的MySQL存儲引擎。在這種情況下,InnoDB表將 非常適合我們的要求,盡管在性能方面可能比MyISAM表要稍遜一籌。大家知道,使用InnoDB表外鍵約束主要優點之一就是,它使我們可以在數據庫級別 處理和維護多個表之間的關系,而無需將此任務推給與這些表打交道的應用程序的某些模塊或者程序庫。
當然,前面的幾篇文章中,我們已經就IndoDB表的外鍵約束做過相應介紹,但是那里都是通過手工方式來操作外鍵約束的。在本文中,我們將說明如何在更新和刪除父表中的數據時,如何通過腳本語言來觸發相應子表的級聯更新和刪除操作。
這里,我們博客應用程序的數據層由兩個表構成,在前面的示例中,對這些表的操作,都是通過手工鍵入SQL命令完成的,現在,我們將介紹如何使用PHP程 序設計語言來完成這些工作。之所以選擇PHP,是因為它目前MySQL最常見的搭配語言,下面我們以PHP 5為例來說明如何外鍵約束操作兩個InnoDB表。 通過閱讀本文,您將更加真切地體會到外鍵約束的特性。
現在,我們開始見證PHP 5和外鍵約束結合在一起所帶來的威力吧!
二、以級聯方式更新和刪除數據庫中的數據
古人云,溫故而知新,那么先讓我們來回顧一下前面學過的內容吧。之前,我們介紹過如何運用外鍵約束級聯更新和刪除存放博客文章評論的InnoDB表中的數據。如果您尚未閱讀前面的文章也不要緊,下面我們簡單回顧這些內容。
這里是我們的示例中用到的兩個表的定義,如下所示:
DROP TABLE IF EXISTS `test`.`blogs`;CREATE TABLE `test`.`blogs` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`title` TEXT,
`content` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `test`.`comments`;
CREATE TABLE `test`.`comments` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`blog_id` INT(10) UNSIGNED DEFAULT NULL,
`comment` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `blog_ind` (`blog_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
上面的代碼定義了兩個表,需要注意一下第二個,因為它為“blog_id”字段規定了一個約束,所以當post表中的數據被更新和刪除時,將觸發相應的級聯操作。
為了幫您理解這一過程,我們可以在表中填上一些數據,這時可以通過SQL語句INSERT來完成,如下:
INSERT INTO blogs (id, title, content, author) VALUES (NULL,'Title of the first blog entry', 'Content of the first blog entry', 'IAN')INSERT INTO comments (id, blog_id, comment, author) VALUES (NULL, 1, 'Commenting first blog entry', 'Tom'), (NULL, 1, 'Commenting first blog entry', 'Rose')
現在,我們唯一的一條博客數據已經有了兩條評論數據,如果由于任何原因需要更新博客及其評論數據的話,可以通過下列命令完成:
UPDATE blogs SET id = 2, title = 'Title of the first blog entry', content = 'Content of the first blog entry', author = 'John Doe' WHERE id = 1這看起來非常簡單,但是,如果我說將博客數據連同相應的評論數據一同刪除會更加簡單,您能會相信嗎?如果不信的話,請看下面的SQL語句:
DELETE FROM blogs WHERE id = 2如您所見,這就是刪除指定博客及其評論所需的全部SQL代碼,這足以證明通過外鍵約束維護兩個InnoDB表的完整性到底有多么的方便。
迄今為止,我們已經簡單回顧之前所學的內容,接下來,我們將繼續探索這些表的約束的各種優點。 就像本文開頭部分介紹的那樣,我們將開始講解如何通過PHP 5內置的MySQL抽象類來生成對我們的示例表的級聯更新。
三、利用PHP 5以級聯方式更新數據庫
好了,現在開始詳細介紹如何使用流行的服務器端腳本語言PHP 5來以級聯方式更新我們的示例表。為此,我們需要編寫允許我們訪問上面定義的InnoDB表的代碼,就本例而言,我們使用PHP 5的MySQL抽象類來達此目的。下面給出具體的代碼:
class MySQL{
private $result = NULL;
private $link = NULL;
//連接到MySQL
public function __construct($host, $user, $password, $database)
{
if (FALSE === ($this->link = mysqli_connect($host, $user, $password, $database)))
{
throw new Exception('Error : ' . mysqli_connect_error());
}
}
//執行查詢
public function query($query)
{
if (is_string($query) AND empty($query) === FALSE)
{
if (FALSE === ($this->result = mysqli_query($this->link, $query)))
{
throw new Exception('Error performing query ' . $query . ' Error message :' .mysqli_error($this->link));
}
}
}
//從結果集返回數據
public function fetch()
{
if (FALSE === ($row = mysqli_fetch_object($this->result)))
{
mysqli_free_result($this->result);
return FALSE;
}
return $row;
}
//獲取插入ID
public function getInsertID()
{
return mysqli_insert_id($this->link);
}
//結果集中的行數
public function countRows()
{
if ($this->result !== NULL)
{
return mysqli_num_rows($this->result);
}
}
//關閉數據庫連接
function __destruct()
{
mysqli_close($this->link);
}
}
如上所示,上面定義的MySQL抽象類十分簡單,它提供了許多常用的方法,用于執行查詢、統計結果集行數以及獲取插入ID。需要格外注意的是,這個類內部使用了PHP擴展mysqli來跟MySQL打交道,所以整體看來是很容易理解的。
好了,我們已經定義了一個可以用于跟MySQL數據庫相交互的PHP 5類,現在我們要做的就是利用它的API對前面定義的InnoDB表執行級聯更新。
四、MySQL抽象類
現在,為了演示如何使用上述的MySQL類級聯更新前文中的數據表,我們需要重新定義那兩個表,以便使其只能執行這些更新的操作。這里是它們的定義,這兩個表將作為我們的示例博客應用程序的數據層:
DROP TABLE IF EXISTS `test`.`blogs`;CREATE TABLE `test`.`blogs` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`title` TEXT,
`content` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `test`.`comments`;
CREATE TABLE `test`.`comments` (
`id` INT(10) UNSIGNED AUTO_INCREMENT,
`blog_id` INT(10) UNSIGNED DEFAULT NULL,
`comment` TEXT,
`author` VARCHAR(45) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `blog_ind` (`blog_id`),
CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`blog_id`) REFERENCES `blogs` (`id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
如上所述,通過給最后一個表中的blog_id字段規定外鍵約束,我們已經把兩個表聯系在了一起,接下來讓我們使用前面定義的MySQL抽象類給它們填 入必要的數據。我們假設這個類被單獨放入一個名為mysqlclass.php文件中,下面的腳本將向blog表中插入單篇博客文章,并向 comments表中插入兩則評論:
require_once 'mysqlclass.php';$db = new MySQL('host', 'user', 'password', 'test');
//在blogs數據庫表中插入新數據
$db->query("INSERT INTO blogs (id, title, content, author) VALUES (NULL,'Title of the first blog entry', 'Content of the first blog entry', 'IAN')");
$insid = $db->getInsertID();
//在comments數據庫表中插入新評論
$db->query("INSERT INTO comments (id, blog_id, comment, author) VALUES (NULL, $insid, 'Commenting first blog entry', 'Tom'), (NULL, $insid, 'Commenting first blog entry', 'Rose')");
雖然我們的這個MySQL類能夠抽象地訪問數據庫,但是相應的SQL查詢還得手工編寫。同時,它正好可以使我們可以展示每當第一個表中的數據更新時,如何使用該類來更新與第一個數據表相關的評論。
執行該級聯更新操作的代碼片斷如下所示:
//更新blogs表中的數據(comments表中的有關數據將自動更新)$db->query("UPDATE blogs SET id = 2, title = 'Title of the first blog entry', content = 'Content of the first blog entry', author = 'John Doe' WHERE id = 1");
盡管另外添加了一個與上述InnoDB表打交道的抽象類,但是觸發級聯更新所需的SQL代碼仍然保持高度簡潔。這說明,各表之間的關系的完整性仍然是在數據庫級別進行維護的,而不是由PHP 5應用程序所維護的。
五、小結
到目前為止,我們詳細講解了如何通過PHP 5內置的抽象類使用外鍵約束來更新兩個InnoDB表中的數據。 我們希望本文能夠對您利用服務器端腳本使用外鍵約束時能夠有所啟發。在后面的文章中,我們將繼續探討外鍵約束有關的內容。
關鍵字:MySQL、數據庫、PHP、服務器
新文章:
- CentOS7下圖形配置網絡的方法
- CentOS 7如何添加刪除用戶
- 如何解決centos7雙系統后丟失windows啟動項
- CentOS單網卡如何批量添加不同IP段
- CentOS下iconv命令的介紹
- Centos7 SSH密鑰登陸及密碼密鑰雙重驗證詳解
- CentOS 7.1添加刪除用戶的方法
- CentOS查找/掃描局域網打印機IP講解
- CentOS7使用hostapd實現無AP模式的詳解
- su命令不能切換root的解決方法
- 解決VMware下CentOS7網絡重啟出錯
- 解決Centos7雙系統后丟失windows啟動項
- CentOS下如何避免文件覆蓋
- CentOS7和CentOS6系統有什么不同呢
- Centos 6.6默認iptable規則詳解