1

さて、私は大学のデータベースを準備するように求められ、特定のデータを特定の方法で保存する必要があります。たとえば、文字の後に 2 つの整数が続くコース コードを保存する必要があるとします。例えば。I45、D61など VARCHAR(3) である必要があります。しかし、これが正しい道であるかどうかはまだわかりません。また、SQL スクリプトでもこれをどのように実施するのかもわかりません。ノートに答えが見つからないようで、現在、スクリプトに干渉する前に、この質問のデータ ディクショナリを作成しています。

任意のヒント?

4

3 に答える 3

4

可能な限り、ビジネス上の意味を持たない主キーを作成します。アプリケーション層側に大きな影響を与えることなく、データベースの設計を簡単に変更できます。愚かな主キーでは、ユーザーは特定のレコードの識別子に意味を関連付けません。

あなたが問い合わせていることはインテリジェントキーと呼ばれ、ほとんどの場合ユーザーに表示されます。ユーザーに見えないキーはダム キーまたは代理キーと呼ばれ、このユーザーに見えないキーが表示されることがありますが、ほとんどのダム キーはユーザーによって解釈されないため、問題にはなりません。例として、この質問のタイトルを変更したい場合、この質問の ID は同じままですhttps://stackoverflow.com/questions/10412621/

インテリジェントな主キーを使用すると、場合によっては審美的な理由から、ユーザーはキーの形式と外観を指定したいと考えます。そして、これはユーザーが感じる頻度で簡単に更新される可能性があります. これは、関連するテーブルの変更をカスケードする必要があるため、アプリケーション側の問題になります。関連するテーブルのキーのカスケード更新には時間がかかるため、データベース側も同様です。

ここで詳細を読む:

http://www.bcarter.com/intsurr1.htm


代理キーの利点: http://en.wikipedia.org/wiki/Surrogate_key

代理キー(別名ダムキー)と一緒に自然キー(別名インテリジェントキー)を実装できます

-- Postgresql has text type, it's a character type that doesn't need length, 
-- it can be upto 1 GB
-- On Sql Server use varchar(max), this is upto 2 GB

create table course
(
    course_id serial primary key, -- surrogate key, aka dumb key

    course_code text unique, -- natural key. what's seen by users e.g. 'D61'

    course_name text unique, -- e.g. 'Database Structure'
    date_offered date
);

このアプローチの利点は、将来のある時点で学校が拡大し、スペイン語対応のデータベース構造を提供することを決定したときです。データベースは、ユーザーが導入したユーザー解釈値から隔離されています。

データベースがインテリジェント キーの使用を開始したとします。

create table course
(
    course_code primary key, -- natural key. what's seen by users e.g. 'D61'

    course_name text unique, -- e.g. 'Database Structure'
    date_offered date
);

その後、スペイン語のデータベース構造コースが始まりました。ユーザーが独自のルールをシステムに導入する場合、これを course_code 値: D61/ESPに入力したくなるかもしれません。他のユーザーはESP-D61ESP:D61として入力します。ユーザーが主キーに関する独自のルールを決定した場合、制御不能になる可能性があります。後で、主キーの形式で作成した任意のルールに基づいてデータをクエリするように指示されます。たとえば、「スペイン語をすべてリストしてください」この学校で提供するコース」、壮大な要件ですね。では、これらの変更をデータベース設計に適合させるために、優れた開発者は何をするでしょうか? 彼/彼女はデータ構造を形式化し、テーブルを次のように再設計します。

create table course
(
    course_code text, -- primary key
    course_language text, -- primary key

    course_name text unique,
    date_offered date,

    constraint pk_course primary key(course_code, course_language)
);

あなたはそれに関する問題を見ましたか?そのコーステーブルに依存するテーブルの外部キーに変更を反映する必要があるため、ダウンタイムが発生します。もちろん、これらの依存テーブルを調整するために最初に必要なものもあります。DBA だけでなく、開発者にも問題が発生する可能性があることを確認してください。

最初から愚かな主キーで始めた場合、ユーザーが知らないうちにシステムにルールを導入したとしても、データベース設計に対する大規模なデータ変更やデータ スキーマの変更は必要ありません。これにより、それに応じてアプリケーションを調整する時間を稼ぐことができます。一方、主キーにインテリジェンスを入れると、上記のようなユーザーの要件により、主キーが自然に複合主キーに移行する可能性があります。これは、データベース設計の再構築やデータの大規模な更新だけでなく、アプリケーションを新しいデータベース設計に迅速に適応させることも困難です。

create table course
(
    course_id serial primary key,
    course_code text unique, -- natural key. what's seen by users e.g. 'D61'
    course_name text unique, -- e.g. 'Database Structure'
    date_offered date
);

そのため、代理キーを使用すると、ユーザーが新しいルールや情報を course_code に隠したとしても、アプリケーションを新しい設計にすばやく適応させることなく、安全にテーブルに変更を導入できます。アプリケーションは引き続き続行でき、ダウンタイムは必要ありません。いつでも、それに応じてアプリを調整するための時間を本当に稼ぐことができます. これは、言語固有のコースへの変更になります。

create table course
(
    course_id serial primary key,

    course_code text, -- natural key. what's seen by users e.g. 'D61'
    course_language text, -- natural key. what's seen by users e.g. 'SPANISH'

    course_name text unique, -- e.g. 'Database Structure in Spanish'
    date_offered date,

    constraint uk_course unique key(course_code, course_language)
);

UPDATEご覧のとおり、依存テーブルの変更を必要としない 2 つのフィールドに course_code でユーザーが課したルールを分割する大規模なステートメントを引き続き実行できます。インテリジェントな複合主キーを使用する場合、データを再構築すると、複合主キーの変更を従属テーブルの複合外部キーにカスケードする必要があります。ダム主キーを使用しても、アプリケーションは通常どおり動作し、新しいデザイン (コース言語用の新しいテキスト ボックスなど) に基づいて、後でいつでもアプリに変更を加えることができます。ダム主キーを使用すると、従属テーブルはコース テーブルを指す複合外部キーを必要とせず、同じ古いダム/サロゲート主キーを引き続き使用できます。

また、ダムの主キーでは、主キーと外部キーのサイズは拡張されません

于 2012-05-02T11:22:18.963 に答える
2

これがドメイン ソリューションです。まだ完璧ではありません。チェックは改善できる可能性があります。

set search_path='tmp';

DROP DOMAIN coursename CASCADE;
CREATE DOMAIN coursename AS varchar NOT NULL
    CHECK (length(value) > 0
    AND  SUBSTR(value,1) >= 'A' AND SUBSTR(value,1) <= 'Z'
    AND  SUBSTR(value,2) >= '0' AND SUBSTR(value,2) <= '9' )
    ;

DROP TABLE course CASCADE;
CREATE TABLE course
    ( cname coursename PRIMARY KEY
    , ztext varchar
    , UNIQUE (ztext)
    );
INSERT INTO course(cname,ztext) 
  VALUES ('A11', 'A 11' ), ('B12', 'B 12' ); -- Ok
INSERT INTO course(cname,ztext)
  VALUES ('3','Three' ), ('198', 'Butter' ); -- Will fail

ところで:「実際の」PKの場合、おそらく代理IDを使用します。しかし、上記のドメイン (UNIQUE 制約付き) は、「論理的な」候補キーとして機能する可能性があります。

これは、基本的に、Table is Domainパラダイムの結果です。

于 2012-05-02T11:53:41.457 に答える
1

データ型についてあまり具体的にしないことを強くお勧めします。そのため、次のようなもので十分ですVARCHAR(8)。理由は次のとおりです。

  • 来年はコードに4文字含まれる可能性があります。ビジネスニーズは常に変化するため、フィールドの長さを制限しすぎないでください
  • アプリケーション層に検証を処理させます-結局のところ、検証の問題をユーザーに伝える必要があります
  • 3文字に制限することで、ビジネス価値をほとんどまたはまったく追加していません。
  • mysqlを使用すると、(値を「検証」するために)列に制約を定義 checkできますが、それらは無視され、互換性の理由でのみ許可されます。

システムのすべてのコンポーネントの中で、データベーススキーマは常に変更が最も難しいため、データ型にある程度の柔軟性を持たせて、可能な限り変更を回避します。

于 2012-05-02T12:04:26.750 に答える