Hallo!
Ich möchte Zugriffsrechte für bestimmte Daten in einer MySQL-Datenbank speichern. Hierfür dachte ich mir, dass man bei jeder Aktion speichert, welche speziellen Benutzer und welche Gruppen von Benutzern sie für welchen Datensatz durchführen können.
Mit einigen Tabellen habe ich das auch hinbekommen, ich bin allerdings sicherlich kein (My)SQL-Guru und mich würde sehr interessieren, ob vielleicht jemand eine bessere Idee hat (insbesondere meine Abfragen mit Sub-Selects sehen recht komplex aus). Wenn mir jemand sagen würde, dass es so in Ordnung ist - auch kein Problem.
Ich habe mal ein kleines Beispiel konstruiert:
-articles: Die Daten, für deren Zugriff Rechte verwaltet werden müssen.
-users: Die Benutzer mit Namen.
-groups: Benutzergruppen mit Namen.
-belonging: n:m-Relation zwischen users und groups.
-acl_users_articles_read: n:m-Relation zwischen den Artikeln und den Benutzern, die sie lesen dürfen.
-acl_groups_articles_read: n:m-Relation zwischen den Artikeln und den Gruppen, deren Mitglieder sie lesen dürfen.
Die Tabellen (MySQL-Export):
--
-- Tabellenstruktur für Tabelle `acl_groups_articles_read`
--
CREATE TABLE IF NOT EXISTS `acl_groups_articles_read` (
`articleid` int(10) unsigned NOT NULL,
`groupid` int(10) unsigned NOT NULL,
UNIQUE KEY `articleid` (`articleid`,`groupid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Daten für Tabelle `acl_groups_articles_read`
--
INSERT INTO `acl_groups_articles_read` (`articleid`, `groupid`) VALUES
(2, 1),
(3, 2),
(4, 3),
(5, 1);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `acl_users_articles_read`
--
CREATE TABLE IF NOT EXISTS `acl_users_articles_read` (
`articleid` int(10) unsigned NOT NULL,
`userid` int(10) unsigned NOT NULL,
UNIQUE KEY `articleid` (`articleid`,`userid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Daten für Tabelle `acl_users_articles_read`
--
INSERT INTO `acl_users_articles_read` (`articleid`, `userid`) VALUES
(2, 1),
(3, 2),
(4, 3),
(5, 4);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `articles`
--
CREATE TABLE IF NOT EXISTS `articles` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` text NOT NULL,
`text` text NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
--
-- Daten für Tabelle `articles`
--
INSERT INTO `articles` (`id`, `name`, `text`) VALUES
(2, 'hallo', 'Hallo du da!'),
(3, 'bla', 'Blablabla'),
(4, 'xyz', 'XYZ!'),
(5, 'abc', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `belonging`
--
CREATE TABLE IF NOT EXISTS `belonging` (
`userid` int(10) unsigned NOT NULL,
`groupid` int(10) unsigned NOT NULL,
UNIQUE KEY `userid` (`userid`,`groupid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Daten für Tabelle `belonging`
--
INSERT INTO `belonging` (`userid`, `groupid`) VALUES
(1, 1),
(1, 3),
(2, 1),
(2, 3),
(3, 2),
(3, 3),
(4, 2),
(4, 3);
-- --------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `groups`
--
CREATE TABLE IF NOT EXISTS `groups` (
`id` int(10) unsigned NOT NULL auto_increment,
`name` varchar(16) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;
--
-- Daten für Tabelle `groups`
--
INSERT INTO `groups` (`id`, `name`) VALUES
(1, 'admins'),
(2, 'users'),
(3, 'all');
Alles anzeigen
Eine Abfrage (uid ist dabei die Benutzer-ID für die gefiltert wird):
SELECT * FROM articles
WHERE uid IN
(SELECT acl_users_articles_read.userid FROM acl_users_articles_read
WHERE acl_users_articles_read.articleid = articles.id)
OR uid IN
(SELECT belonging.userid FROM belonging
WHERE belonging.groupid IN
(SELECT acl_groups_articles_read.groupid FROM acl_groups_articles_read
WHERE acl_groups_articles_read.articleid = articles.id)
)
Danke im Voraus!
The User