2

私は製造DBの一部に取り組んでいます。ビジネスはカスタムオーダーを受け取り、仕様に合わせてアイテムを構築します。数種類 (3 ~ 10 としましょう) のオブジェクトのみを作成しますが、オブジェクトの種類ごとに記録される仕様が異なります。いくつかの共通フィールドをリストしたマスター製造テーブル (mfgorders) を作成し、注文したエンティティに固有の仕様テーブルを参照させたいと考えています。これが正しいアプローチであると完全に確信しているわけではありません。実は私も自信がありません。私の他のモデリングはすべて簡単ですが、これは私を悩ませています.

SQLは次のとおりです。

CREATE TABLE dbo.mfgorders (MfgOrderId int NOT NULL
                                       IDENTITY (1, 1) ,
                        OrderId int NOT NULL,
                        LineNbr tinyint NOT NULL,
                        MfgTypeId tinyint NOT NULL,
                        ItemDescription varchar (999) ,
                        ManufacturingCost smallmoney,
                        CONSTRAINT PK_mfgorders PRIMARY KEY (MfgOrderId)) ;
--OrderId + LineNbr are a composite referencing a row on a lineitem table (not depicted here)

CREATE TABLE dbo.mfgorders_entity1 (MfgOrderId int NOT NULL,
                                EntitySize decimal (5, 3) ,
                                Width decimal (4, 2) ,
                                Thickness decimal (4, 2) ,
                                CONSTRAINT PK_mfgorders_entity1 PRIMARY KEY (MfgOrderId)) ;

CREATE TABLE dbo.mfgorders_entity2 (MfgOrderId int NOT NULL,
                                Height decimal (5, 2) ,
                                Width decimal (5, 2) ,
                                Thickness decimal (4, 2) ,
                                RotationSetting decimal (4, 1) ,
                                FinishedHeight decimal (5, 2) ,
                                FinishedWidth decimal (5, 2) ,
                                FinishedThickness decimal (4, 2) ,
                                CONSTRAINT PK_mfgorders_entity2 PRIMARY KEY (MfgOrderId)) ;

CREATE TABLE mfg_types (MfgTypeId tinyint NOT NULL,
                    ItemName varchar (32) NOT NULL,
                    ItemDescription nvarchar (64) NULL,
                    IsActive bit NOT NULL
                                 CONSTRAINT DF_mfg_types_IsActive DEFAULT 1,
                    SortOrder int NULL,
                    CONSTRAINT PK_mfg_types PRIMARY KEY (MfgTypeId)) ;

ALTER TABLE dbo.mfgorders_entity1 ADD CONSTRAINT FK_mfgorders_entity1_mfgorders FOREIGN KEY (MfgOrderId) REFERENCES dbo.mfgorders (MfgOrderId) ON UPDATE NO ACTION ON DELETE CASCADE;

ALTER TABLE dbo.mfgorders_entity2 ADD CONSTRAINT FK_mfgorders_entity2_mfgorders FOREIGN KEY (MfgOrderId) REFERENCES dbo.mfgorders (MfgOrderId) ON UPDATE NO ACTION ON DELETE CASCADE;

ALTER TABLE dbo.mfgorders ADD CONSTRAINT FK_mfgorders_mfg_types FOREIGN KEY (MfgTypeId) REFERENCES dbo.mfg_types (MfgTypeId) ON UPDATE NO ACTION ON DELETE CASCADE;

上記のコードのER図は次のとおりです。

ER図

このモデルは、entity1 と entity2 が同じ MfgOrderId を持つことができることを意味しますが、もちろんそれは望ましくありません。MfgOrderId が 1 つのエンティティのみを参照するようにします。mfg_types を使用して適切なエンティティ テーブルを指すことを望んでいたと思いますが、モデルがオフになっていると感じており、SO コミュニティに問い合わせて、私の人生に数年余分に追加したいと考えています。

よろしく、ジョン

4

3 に答える 3

2

「…そしてもちろん、私はそれを望んでいません。」

私は必ずしもその結論に飛びつくつもりはありません。あなたが説明しているモデルは許容できるものです.Hibernateはそれを呼び出しますInheritanceType.JOINED. ドキュメントでそれについて読むことができますが、同じ ID を共有するすべてのテーブルとの関係をモデル化します。

JPAのドキュメントでもそれについて話しています。

これを使用すること、または実際にデータベースでクラス階層を一般的に表現することに関する重要な部分は、entity1 または entity2 のどちらを持っているかを知ることができる必要があるということです。これを行う最も明確な方法はDiscriminatorを使用することです。これは基本的に、行がエンティティ 1 またはエンティティ 2 を表すかどうかを示すスーパークラス テーブル内の列です。

Discriminator を指定せず、JOINED を使用している場合、Hibernate (およびおそらく他の JPA 実装) は、すべてのサブクラス テーブルをチェックし、どのテーブルに特定の ID を持つ行が含まれているかを確認することで、自動的にそれを行うと思います。 . すべての MfgOrderId が 1 つのサブクラス テーブルにあると仮定すると、これはスキーマを変更しなくても機能します。

編集

誤って TABLE_PER_CLASS を切り替えました。JOINED を意味していました!

于 2013-02-14T19:32:35.920 に答える
1

あなたのデザインが表現している、または試みているのは、スーパータイプとサブタイプの関係です。

これを表現する1つの方法はMfgTypeId、各エンティティテーブルにフィールドを含めることです。

CREATE TABLE dbo.mfgorders_entity2 (MfgOrderId int NOT NULL,
                 MfgTypeId tinyint NOT NULL,
                 Height decimal (5, 2) ,
                 Width decimal (5, 2) ,
                 Thickness decimal (4, 2) ,
                 RotationSetting decimal (4, 1) ,
                 FinishedHeight decimal (5, 2) ,
                 FinishedWidth decimal (5, 2) ,
                 FinishedThickness decimal (4, 2) ,
                 CONSTRAINT PK_mfgorders_entity2 PRIMARY KEY (MfgOrderId, MfgTypeId),
                 CONSTRAINT chkEntity2_MfgTypeID CHECK (MfgTypeId = 'Type Id for Entity 2')) ;

おそらく、MfgOrdersテーブルを変更して、主キーの一部としてMfgTypeIdも含めるようにします。

CREATE TABLE dbo.mfgorders (MfgOrderId int NOT NULL IDENTITY (1, 1) ,
                 MfgTypeId tinyint NOT NULL,                 
                 OrderId int NOT NULL,
                 LineNbr tinyint NOT NULL,
                 ItemDescription varchar (999) ,
                 ManufacturingCost smallmoney,
                 CONSTRAINT PK_mfgorders PRIMARY KEY (MfgOrderId, MfgTypeId)) ;

Supertype&Subtypeデータベースモデリングを検索すると、SOやStackexchangeネットワークに関する質問など、多くのリソースが見つかります。これを始めるのに役立つかもしれないいくつかのリンクを以下に含めました:

  1. データベース管理者のスーパータイプ/サブタイプ

  2. スーパータイプとサブタイプ

  3. サブタイプ内の参照整合性を実装する方法

于 2013-02-14T19:52:41.943 に答える
0

あなたが持っているものに大きな問題は見られません。これが私がおそらくすることです:

CREATE TABLE dbo.mfgorders (    MfgOrderId int NOT NULL IDENTITY (1, 1),
                            OrderId int NOT NULL,
                            LineNbr tinyint NOT NULL,
                            MfgTypeId tinyint NOT NULL,
                            ItemDescription varchar (999) ,
                            ManufacturingCost smallmoney,
                            CONSTRAINT PK_mfgorders PRIMARY KEY (MfgOrderId)) ;
--OrderId + LineNbr are a composite referencing a row on a lineitem table (not depicted here)

CREATE TABLE dbo.mfgorders_entity1( MfgOrderEntity1Id int NOT NULL IDENTITY (1, 1),
                                MfgOrderId int NOT NULL,
                                EntitySize decimal (5, 3) ,
                                Width decimal (4, 2) ,
                                Thickness decimal (4, 2) ,
                                CONSTRAINT PK_mfgorders_entity1 PRIMARY KEY (MfgOrderEntity1Id)) ;

CREATE TABLE dbo.mfgorders_entity2 (MfgOrderEntity2Id int NOT NULL IDENTITY (1, 1),
                                MfgOrderId int NOT NULL,
                                Height decimal (5, 2) ,
                                Width decimal (5, 2) ,
                                Thickness decimal (4, 2) ,
                                RotationSetting decimal (4, 1) ,
                                FinishedHeight decimal (5, 2) ,
                                FinishedWidth decimal (5, 2) ,
                                FinishedThickness decimal (4, 2) ,
                                CONSTRAINT PK_mfgorders_entity2 PRIMARY KEY (MfgOrderEntity2Id)) ;

CREATE TABLE mfg_types (            MfgTypeId tinyint NOT NULL,
                                ItemName varchar (32) NOT NULL,
                                ItemDescription nvarchar (64) NULL,
                                IsActive bit NOT NULL
                                CONSTRAINT DF_mfg_types_IsActive DEFAULT 1,
                                SortOrder int NULL,
                                CONSTRAINT PK_mfg_types PRIMARY KEY (MfgTypeId)) ;

ALTER TABLE dbo.mfgorders_entity1 ADD CONSTRAINT FK_mfgorders_entity1_mfgorders FOREIGN KEY (MfgOrderId) REFERENCES dbo.mfgorders (MfgOrderId) ON UPDATE NO ACTION ON DELETE CASCADE;

ALTER TABLE dbo.mfgorders_entity2 ADD CONSTRAINT FK_mfgorders_entity2_mfgorders FOREIGN KEY (MfgOrderId) REFERENCES dbo.mfgorders (MfgOrderId) ON UPDATE NO ACTION ON DELETE CASCADE;

ALTER TABLE dbo.mfgorders ADD CONSTRAINT FK_mfgorders_mfg_types FOREIGN KEY (MfgTypeId) REFERENCES dbo.mfg_types (MfgTypeId) ON UPDATE NO ACTION ON DELETE CASCADE;
于 2013-02-14T19:40:14.437 に答える