基本上我想要一个中间人Book
,介于从Line
到User
的直接链接之间。 Line
元素已经存在且无法与相应的现有User
元素失去关系,因此需要创建一个处理现有数据的默认Book
元素。
表格是这样创建的:
User (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(50) NOT NULL
);
Line (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(300),
id_user INT UNSIGNED NOT NULL,
FOREIGN KEY (id_user) REFERENCES User(id)
);
现在我需要创建一些可以产生这样的表的SQL代码:
User (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(50) NOT NULL
);
Book (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(300),
id_user INT UNSIGNED NOT NULL,
FOREIGN KEY (id_user) REFERENCES User(id)
);
Line (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(300),
id_book INT UNSIGNED NOT NULL,
FOREIGN KEY (id_book) REFERENCES Book(id)
);
...除了数据已经存在。所以我有Line元素指向User元素,我不能从头开始创建新表。所以我需要SQL代码来修改现有的结构。
基本上我只是希望用户拥有书籍和书籍,而不是用户有行。并且已经存在的线路与所有者用户建立连接。什么是最好的方法?
/////////////////////////////////////////////// ////////
表示我的数据库当前状态的一些示例数据:
Table user(id,username)
- 1, user1
- 2, user2
- 3, user3
Table line(id,title,id_user)
- 1, line1, 1
- 2, line2, 1
- 3, linex, 1
- 4, line1, 2
- 5, liney, 2
输出应该是以下数据库:
Table user(id,username)
- 1, user1
- 2, user2
- 3, user3
Table book(id,title,id_user)
- 1, 'default', 1
- 2, 'default', 2
- 3, 'default', 3
Table line(id,title,id_book)
- 1, line1, 1
- 2, line2, 1
- 3, linex, 1
- 4, line1, 2
- 5, liney, 2
////////////////////////////////
我的管道目前是什么样的,我的主要问题是产生最终查询:
create table book
$sql = "CREATE TABLE IF NOT EXISTS book(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(300),
id_user INT UNSIGNED NOT NULL,
FOREIGN KEY (id_user) REFERENCES User(id)
); ";
$conn->exec($sql);
//insert default book corresponding to every user
$sql = "INSERT INTO Book(title, id_user) SELECT DISTINCT 'default', id FROM User;";
$conn->exec($sql);
//insert id_book foreign key into Line table pointing to Book table
$sql = "ALTER TABLE Line ADD id_book INT;"
$conn->exec($sql);
//make Line.id_book foreign key pointing to Line.id
$sql="ALTER TABLE Line ADD FOREIGN KEY (id_book) REFERENCES User(id);"
$conn->exec($sql);
//unfinished
$sql = "UPDATE
Line
SET
Line.id_book = Book.id
WHERE
Line.id_user = Book.id_user"
答案 0 :(得分:1)
创建表book
(就像你已经做过的那样):
CREATE TABLE IF NOT EXISTS book(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(300),
id_user INT UNSIGNED NOT NULL,
FOREIGN KEY (id_user) REFERENCES User(id)
);
填充新表格:
INSERT INTO Book(title, id_user) SELECT 'default', id FROM User;
我从您的代码中删除了DISTINCT
,因为id
是主要/唯一的,因此每个选定的行都保证是唯一的。
将列id_book
添加到line
表:
ALTER TABLE Line ADD id_book INT UNSIGNED;
必须INT UNSIGNED
才能匹配引用的数据类型。
添加外键:
ALTER TABLE Line ADD FOREIGN KEY (id_book) REFERENCES book(id);
它应该引用一本书,而不是代码中的用户。
更新数据(与用户(第一)书相关联的行):
UPDATE Line
SET Line.id_book = (
SELECT book.id
FROM book
WHERE book.id_user = Line.id_user
ORDER BY book.id
LIMIT 1
);
删除line.id_user
列:
-- use "SHOW CREATE TABLE line" to find out the foreign key name
ALTER TABLE Line DROP FOREIGN KEY line_ibfk_1;
ALTER TABLE Line DROP id_user;
http://sqlfiddle.com/#!9/3faa13/1
注意:如果用户有两本或更多书,您就不知道哪一本要与line
相关联。在您的问题中,您没有定义如何处理此案例。所以我决定在id
(ORDER BY book.id LIMIT 1
)之后拿出第一本书。
UPDATE语句也可以是:
UPDATE Line
SET Line.id_book = (
SELECT MIN(book.id)
FROM book
WHERE book.id_user = Line.id_user
);