私は中規模の MySQL データベースを持っており、主要な「persons」テーブルには、私が多数の Web アプリケーションの保守と開発を担当している劇場および演劇学校に接続しているすべての人間に関する基本的な連絡先情報が含まれています。
一部の人は単なる連絡先です。つまり、「persons」テーブル レコードは、その人について保存する必要があるすべての情報です。しかし、他の多くの人は、さまざまなシステムに対して異なる役割を引き受けることができなければなりません。このうち、ほとんどが学生としてスタートします。正社員としてスタートする方もいます。学生はインターンやパフォーマーになることができます。従業員は学生になることができます。すべての教師は従業員とパフォーマーなどです。
本質的に、それらは、システムのさまざまな部分にアクセスして対話するために、またそれらに関する情報を私たちのサイトの公開ページで利用できるようにするために、個人が着用しなければならないさまざまな「帽子」です。
このモデルを実装するための私の選択は、これらの「帽子」を表す他のいくつかのテーブルを用意することです。基本的な「人」情報を補足するメタ情報を含むテーブルで、すべて「人」ID を主キーとして使用します。たとえば、教師である人物は、彼または彼女の簡単な経歴情報と給与を含むレコードを教師テーブルに持っています。すべての教師は従業員でもあります (ただし、すべての従業員が教師であるわけではありません)。つまり、従業員テーブルにレコードがあり、給与システムに勤務時間を送信できます。
私の質問は、モデルをそのまま実装することの欠点は何ですか? 私が考えることができる唯一の他のオプションは、ほとんどのエントリに対して空で役に立たないフィールドで個人テーブルを膨らませ、次に個人が属することができる「グループ」の面倒なテーブルを持ち、次にすべてのほぼすべてのテーブルを持つことですシステムは個人person_id
の外部キーを持ち、ビジネス ロジックに依存して、参照されている person_id が適切なグループに属していることを確認します。しかし、それはばかげていますね。
以下にいくつかのテーブル宣言の例を示します。これは、私が現在これらすべてをどのようにまとめているかを示し、システムが対処しなければならないさまざまな状況の現実をモデル化するためのより賢明な方法であると私が考える理由を示していることを願っています.
あらゆる提案やコメントを歓迎します。お時間をいただきありがとうございます。
EDIT何人かの回答者が、セキュリティのために ACL を使用することについて言及しています。最初の質問では、実際には、さまざまなシステムの実際のユーザーのきめ細かいアクセス制御のために別の ACL パッケージを使用していることには言及していませんでした。私の質問は、データベース スキーマに人に関するメタデータを格納するためのベスト プラクティスに関するものです。
CREATE TABLE persons (
`id` int(11) NOT NULL auto_increment,
`firstName` varchar(50) NOT NULL,
`middleName` varchar(50) NOT NULL default '',
`lastName` varchar(75) NOT NULL,
`email` varchar(100) NOT NULL default '',
`address` varchar(255) NOT NULL default '',
`address2` varchar(255) NOT NULL default '',
`city` varchar(75) NOT NULL default '',
`state` varchar(75) NOT NULL default '',
`zip` varchar(10) NOT NULL default '',
`country` varchar(75) NOT NULL default '',
`phone` varchar(30) NOT NULL default '',
`phone2` varchar(30) NOT NULL default '',
`notes` text NOT NULL default '',
`birthdate` date NOT NULL default '0000-00-00',
`created` datetime NOT NULL default '0000-00-00 00:00',
`updated` timestamp NOT NULL,
PRIMARY KEY (`id`),
KEY `lastName` (`lastName`),
KEY `email` (`email`)
) ENGINE=InnoDB;
CREATE TABLE teachers (
`person_id` int(11) NOT NULL,
`bio` text NOT NULL default '',
`image` varchar(150) NOT NULL default '',
`payRate` float(5,2) NOT NULL,
`active` boolean NOT NULL default 0,
PRIMARY KEY (`person_id`),
FOREIGN KEY(`person_id`) REFERENCES `persons` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;
CREATE TABLE classes (
`id` int(11) NOT NULL auto_increment,
`teacher_id` int(11) default NULL,
`classstatus_id` int(11) NOT NULL default 0,
`description` text NOT NULL default '',
`capacity` tinyint NOT NULL,
PRIMARY KEY(`id`),
FOREIGN KEY(`teacher_id`) REFERENCES `teachers` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY(`classstatus_id`) REFERENCES `classstatuses` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
KEY (`teacher_id`,`level_id`),
KEY (`teacher_id`,`classstatus_id`)
) ENGINE=InnoDB;
CREATE TABLE students (
`person_id` int(11) NOT NULL,
`image` varchar(150) NOT NULL default '',
`note` varchar(255) NOT NULL default '',
PRIMARY KEY (`person_id`),
FOREIGN KEY(`person_id`) REFERENCES `persons` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;
CREATE TABLE enrollment (
`id` int(11) NOT NULL auto_increment,
`class_id` int(11) NOT NULL,
`student_id` int(11) NOT NULL,
`enrollmenttype_id` int(11) NOT NULL,
`created` datetime NOT NULL default '0000-00-00 00:00',
`modified` timestamp NOT NULL,
PRIMARY KEY(`id`),
FOREIGN KEY(`class_id`) REFERENCES `classes` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY(`student_id`) REFERENCES `students` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE,
FOREIGN KEY(`enrollmenttype_id`) REFERENCES `enrollmenttypes` (`id`)
ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE=InnoDB;