我有一些看起来像这样的东西:
if ( $_SESSION['username'] )
$owner = $_SESSION['username'];
$q = "SELECT * FROM projects where owners='$owner' ORDER BY created DESC";
问题是'所有者'列可能有多个用逗号分隔的条目。我需要一种循环遍历所有条目的方法,并在所有者列中选择任何具有$ owner的表。什么是最好的解决方法?
答案 0 :(得分:1)
关系数据库的正确设计是只在给定的“单元格”中存储一个值(即在给定行的给定列中 - 但请不要在关系数据库中使用电子表格术语,您将{ {3}}哭泣: - )。
以下是一个例子:
CREATE TABLE Projects (
project_id INT PRIMARY KEY,
...
);
CREATE TABLE Users (
user_id INT PRIMARY KEY,
...
);
CREATE TABLE Project_Owners (
project_id INT NOT NULL,
user_id INT NOT NULL,
PRIMARY KEY (project_id, user_id),
FOREIGN KEY (project_id) REFERENCES Projects(project_id),
FOREIGN KEY (user_id) REFERENCES Users(user_id)
);
为给定项目的每个所有者向Project_Owners表插入一行。因此,您可以轻松地拥有一个包含多个所有者的项目,以及一个处理多个项目的用户。
我们说项目与用户有多对多关系。
因此,当您想要获得与给定所有者关联的项目时,您需要在users表中查找所有者,然后通过多对多表将其加入项目:
<?php
$owner = mysql_real_escape_string($_SESSION["username"]);
$sql = "SELECT p.* FROM Projects
INNER JOIN Project_Owners o USING (project_id)
INNER JOIN Users u USING (user_id)
WHERE u.name = '$owner'";
或者如果您想简化它,可以在会话数据中使用整数。然后你可以跳过加入:
<?php
$owner = (int) $_SESSION["username"];
$sql = "SELECT p.* FROM Projects
INNER JOIN Project_Owners o USING (project_id)
WHERE o.user_id = $owner";
在单元格中只存储一个值的概念是Joe Celko的基本定义的一部分。任何关于SQL的书都应该涵盖这一点,即使是First Normal Form。