わかりました、興味深いですが、なぜ3NFを使用したいのですか?
MVC Webフレームワーク(Codeigniter、Zend Framework、Ruby on Railsなど)では、3NFは必要なく、さまざまなテーブルについても気にする必要はありません。あなたが試みているのは、複数のテーブルの継承ですが、これはあまり一般的ではありません。
つまり、実際には、たとえば、Custumer
Customer、User、Personテーブルにあるすべての属性を持つクラスがあります。MVCとシンコントローラーのアプローチに固執するには、これらの属性を受け入れ、このクラスからオブジェクトをインスタンス化するsave
アクションをクラスに含める必要があります。CustomerController
Costumer
class CostumerController {
function create() {
Costumer c = new Customer();
c.save($_POST['costumer']);
}
}
(必ず、SQLインジェクションのパラメーターを確認してください。ただし、フレームワークはそれを何らかの方法で処理する必要があります。)
カスタムクラスには、すべての属性を受け入れて適切なテーブルに保存するコンストラクターが必要です。すなわち:
class Costumer {
function save(params) {
$sql = 'INSERT INTO person SET `phoneNumber` = "' . params['phonenumber'] . '"';
$dbh->query($sql);
$lastid = PDO::lastInsertId;
$sql = 'INSERT INTO user SET `password` = "'. md5(params['password']) . '", `personId` = "' . $lastid . '";
...
}
}
お気づきかもしれませんが、CodeIgniterがわからないため、SQLステートメントと一部のコードを短縮しました。ただし、必要なすべてのデータを、データベース内の適切なテーブルに保存するsaveメソッドに渡すという考え方です。
注意: MVCのデータベースと通信するのはモデルクラスのみです。
問題は、他のテーブルで外部キーとして使用するIDです。したがって、データを人に挿入した後、挿入したIDをテーブルに照会して、別のテーブルで使用する必要があります。
そのため、一部のフレームワーク(つまり、私が知っているすべてのフレームワーク)は、デフォルトで単一テーブル継承を使用します。このように想像してください:
あなたがそれを説明したように、あなたのCostumer
継承者はからUser
継承しPerson
ます。これらのテーブルはすべて1つのテーブルにマージされます。このテーブルには、type
その行のオブジェクトがこの場合は、、またはのどのタイプであるかを示す属性Customer
もUser
ありますPerson
。ユーザーのみを追加する場合、未使用の属性はすべてに設定されNULL
ます。もちろん、これはあなたの3NFを壊します。
しかし、私が理解していないのは、あなたが常に1:1の関係を必要とする理由です。たとえば、Person
との間Company
。ああ、今私はそれを手に入れました、にがないのでcompanyId (FK)
、Person
多くPerson
のsが1つに入ることができますCompany
。しかし、なぜがBranch
ありますかpersonId (FK)
。通常、支店で働く人はもっといますよね?
質問に戻る
私は最初のものを好みますが、 thin-controller-fat-modelまたはfat-controller-thin-modelのいずれかを使用できます。この場合、コントローラーには数行しかなく、モデルにはさらに多くのロジックがあります(上記の例のように)。データベースとの通信は、モデルクラスでのみ行われます。通常、one-table-equals-one-model-typeアプローチはありませんが、複数のモデルタイプが1つのテーブルにアクセスする場合もあります(単一テーブル継承を参照)。
別のアプローチ
Costumer
データを受け入れ、テーブルが「分散」する方法でデータを「グループ化」するモデルを作成できます。
class Customer {
function save(params) {
Person $person = new Person();
$person.save(params['person']);
User $user = new User();
$user.save(params['user'], $person->id);
....
}
}
しかし...まあ、私が言ったように、私はあなたが3NFアプローチを離れて、STI(単一テーブル継承)を使用することを提案します。
SQLインジェクションを回避するためにフォームデータを引用することを忘れないでください。または、フレームワークがそれを実行するために提供する関数を確認してください。
コードに誤りがあったことをお詫びします。私はメモリから「コーディング」しているだけで、構文解析もしていませんでした。
HTH