這非常迅速複雜化,我開始質疑數據庫設計。 應用程序的基本概念是:MySQL使用A表的行值連接三個表格
- 用戶帳戶
- 特點
- 訪問級別
因此,用戶必須爲每個功能不同的訪問級別。我會想到的是相當基本和普遍的應用。
模式:
CREATE TABLE `user_accounts` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_login` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`user_password` varchar(60) COLLATE utf8_unicode_ci NOT NULL,
`user_fname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`user_lname` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`user_group` varchar(32) COLLATE utf8_unicode_ci NOT NULL DEFAULT 'Default',
PRIMARY KEY (`id`),
UNIQUE KEY `user_login` (`user_login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
INSERT INTO `user_accounts` VALUES(1, '[email protected]', 'secret', 'Example', 'Name', 'Admin');
INSERT INTO `user_accounts` VALUES(2, '[email protected]', 'secret', 'John', 'Doe', 'Trainer');
INSERT INTO `user_accounts` VALUES(3, '[email protected]', 'secret', 'Jane', 'Doe', 'Default');
CREATE TABLE `user_access_meta` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `type` (`type`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `user_access_meta` VALUES(1, 'type_1');
INSERT INTO `user_access_meta` VALUES(2, 'type_2');
INSERT INTO `user_access_meta` VALUES(3, 'type_3');
INSERT INTO `user_access_meta` VALUES(4, 'type_4');
INSERT INTO `user_access_meta` VALUES(5, 'type_5');
INSERT INTO `user_access_meta` VALUES(6, 'type_6');
CREATE TABLE `user_access_levels` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_login` varchar(100) COLLATE utf8_unicode_ci NOT NULL,
`type` varchar(50) COLLATE utf8_unicode_ci NOT NULL,
`level` int(1) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `user_login_2` (`user_login`,`type`),
KEY `user_login` (`user_login`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci ;
INSERT INTO `user_access_levels` VALUES(1, '[email protected]', 'type_1', 1);
INSERT INTO `user_access_levels` VALUES(2, '[email protected]', 'type_2', 1);
INSERT INTO `user_access_levels` VALUES(3, '[email protected]', 'type_3', 0);
INSERT INTO `user_access_levels` VALUES(4, '[email protected]', 'type_5', 2);
INSERT INTO `user_access_levels` VALUES(5, '[email protected]', 'type_2', 1);
INSERT INTO `user_access_levels` VALUES(6, '[email protected]', 'type_3', 1);
INSERT INTO `user_access_levels` VALUES(7, '[email protected]', 'type_5', 3);
INSERT INTO `user_access_levels` VALUES(8, '[email protected]', 'type_4', 1);
這些表其實有很多的字段,並在它們之間具有外鍵約束,但我已經條紋下來的這個例子。它們也被單獨用於其他目的。
我已經成功地能夠加入所有三個表一起與此單個用戶:
SELECT
ua.`user_fname`,
uam.`type`,
ual.`level`
FROM `user_access_meta` uam
LEFT JOIN `user_access_levels` ual
ON ual.`user_login` = '[email protected]'
AND uam.`type` = ual.`type`
JOIN `user_accounts` ua
ON ua.`user_login` = '[email protected]';
輸出:
| USER_FNAME | TYPE | LEVEL |
--------------------------------
| Example | type_1 | 1 |
| Example | type_2 | 1 |
| Example | type_3 | 0 |
| Example | type_4 | (null) |
| Example | type_5 | 2 |
| Example | type_6 | (null) |
即使這是不理想的,但是這就是我可以拿出來,它的目的。
現在,我需要做的是選擇所有用戶,包括他們的訪問級別。這將是這個樣子:
| USER_FNAME | type_1 | type_2 | type_3 | type_4 | type_5 | type_6 |
--------------------------------------------------------------------------
| Example | 1 | 1 | 0 | (null) | 2 | (null) |
| John | (null) | 1 | 1 | (null) | 3 | (null) |
| Jane | (null) | (null) | (null) | 1 | (null) | (null) |
我覺得這可能不是最好的設計,但我有這樣的設計去的原因是,我可以輕鬆地添加和刪除功能,甚至暫時單獨禁用它們。
設計應該重新考慮嗎?用這種設計能夠獲得我期待的結果嗎?
我已經把它放在SQL小提琴上。 http://sqlfiddle.com/#!2/bb313/2/0
感謝您對這樣一個偉大的答案!我相信第二個版本會起作用,但是當我在phpMyAdmin中運行查詢時,我得到'給予EXECUTE'的未知準備好的語句處理程序(stmt),我只是不熟悉準備好的語句,知道這意味着什麼。我已經做了一些研究,但是我覺得我可能會走錯路,因爲我會從PHP查詢數據庫。當我從PHP(PDO)調用它時,我從'fetchAll()'得到一個空數組,並且沒有錯誤。感謝您的回答,這非常有幫助,我學到了很多東西。 – JDavis 2012-08-23 00:43:16
@JDavis不幸的是我現在沒有MySQL的副本。我會看看我能否弄清楚。 – Taryn 2012-08-23 00:54:09