sql >> データベース >  >> RDS >> Mysql

主キーSQLチュートリアル–データベースで主キーを定義する方法

    すべての素晴らしい物語はアイデンティティの危機から始まります。偉大なジェダイマスターであるルークは、確信が持てなくなります-「私は誰ですか?」 -そして、どうすれば私は誰か重要になることができますか?フォースを持っているヨーダが自分の力を活かす方法を教えるには、ヨーダが必要です。

    今日は私をあなたのヨーダにしましょう。

    主キーを選択する方法から始めて、IDの危機に立ち向かい、データベースに主キーを作成するためのコードサンプルで終わります。

    主キーの選択方法

    アイデンティティの危機に直面しているのはルークだけだと思う​​かもしれませんが、そうではありません。データベースを作成するとき、すべてがアイデンティティの危機に陥っています。そしてそれがまさに私たちが主キーを必要とする理由です:それらは危機を解決します。全員を見つける方法を教えてくれます。

    あなたが政府であり、市民の一人一人をデジタルで識別したいとします。したがって、これらに関するすべてを使用してこのデータベースを作成します。

    First Name
    Last Name
    Passport Number

    主キーとしてパスポート番号を選択します。これは全員のIDです。パスポートには住所とその他すべてが含まれているので、必要なのはそれだけだと思います。パスポート番号は一意であることがわかっているので、気分が良く、このシステムを実装できます。

    それから数年後、あなたは醜い真実を見つけます:国全体がアイデンティティの危機に直面しています。

    誰かのパスポートの有効期限が切れると、新しいパスポートを取得します。彼らのアイデンティティは変わります。他のシステムは古いパスポート番号を使い続けるので、今では幽霊の人を指しています。

    一意性だけでは不十分です。値は、行の存続期間を通じて変更してはなりません。

    そして、パスポートすら持っていない人もいます。主キーをNULLにすることはできないため、システムに入力することはできません。 。 NULLで誰かを特定するにはどうすればよいですか キー?

    すべての行に識別子が必要です。 NULLは許可されていません。

    次の反復は、時間の経過とともに変化しない識別子と、誰もが持っている識別子を見つけることを意味します。インドでは、これがAdhaarカードであることが判明しています。米国では、社会保障番号。

    データベースを作成する場合は、それらを主キーにします。

    時々、あなたはそのような鍵を持っていません。社会保障番号をまだ持っていない国を考えてみましょう。彼らはすべての市民のデジタル記録を作成したいと考えています。新しいSSNを作成することも、データベースの機能を活用して代理キーを使用することもできます。

    代理キーには、実世界に相当するものはありません。これは、データベース内の単なる数値です。つまり、新しい国にこのテーブルがあります:

    userID
    First Name
    Last Name
    Passport Number

    パスポート番号は一意です。ユーザーの識別子を取得したいときはいつでも、パスポート番号を介して取得できます。

    userIDは変更されません。パスポート番号は変更される可能性がありますが、常に一意であるため、常に適切なユーザーを取得できます。 userIDは代理です この国に存在しない社会保障番号の場合。

    おもしろい事実:ここのパスポート番号は候補キーでもあります。それが変更されなかった場合、それは主キーであった可能性があります。これはビジネスロジックの違いです。

    主なポイントは次のとおりです。主キーを選択するときはいつでも、アイデンティティの危機について考えてください 。将来誰かが自分の識別子を変更する可能性はありますか?同じ識別子を持つ複数の人がいる状態に入ることができますか?

    私は例として人を使用します。なぜなら、それはアイデンティティをより明確にするからです-私たちはすべての人がアイデンティティを持っていることになっていることを知っています。この考えをデータベースに移します。すべてにアイデンティティがあります。そのため、主キーが必要です。

    注:主キーとして複数の列を一緒に使用することが可能であり、望ましい場合があります。これは複合キーです。

    それでは、実際のコード例を使用して主キーを定義してみましょう。ここで行うことは2つあります。最初に、主キーを識別します。次に、データベースで定義するための構文を学習します。

    実世界の例

    Flexportのように、出荷のスタートアップを運営しているとしましょう。ある場所から別の場所に移動する必要のあるパッケージと、それらを輸送する船があります。さらに、これらのパッケージを注文している顧客がいます。

    顧客用に1つ、パッケージ用に1つ、輸送用に1つのテーブルが必要であり、現在どのパッケージがどこにあるかを示します。

    必要な列と、主キーとなるものを検討してください。あなたがフレックスポートのエンジニアだった場合、これはあなたが理解しなければならない実際の質問です。何も与えられず、すべてが現実の世界で発見されます。

    この情報を考慮して、これらのテーブルを次のように設計します。

    Customers: first_name, last_name, email, address (for deliveries to their location)
    Packages: weight, content
    Transportation: <package_primary_key>, Port, time

    主キーがありません。さらに読む前にそれらについて考えてください。

    パッケージには、代理を選択します PackageID。パッケージのすべての属性(重量、体積、密度、年齢)を一覧表示することもできます。彼らはパッケージを一意に識別しますが、これを実際に行うのは非常に困難です。人々はこれを気にしません、彼らはただある場所から別の場所に移動するパッケージを気にします。

    したがって、ランダムな番号を作成し、それをIDとして使用することは理にかなっています。これがまさに、FedEx、UPS、およびすべての配送サービスがバーコードとIDを使用している理由です。これらは、パッケージを追跡するために生成される代理キーです。

    お客様には、代理を選択します 顧客ID。ここでも、たとえば、顧客の社会保障番号を選択するオプションがありました。しかし、顧客は私が何かを出荷できるようにするためだけにこれを私と共有することを望んでいません。したがって、内部でキーを生成し、このキーについてお客様に通知せず、引き続きCustomerNoと呼びます。 345681。

    おもしろい話:このCustomerNoを公開した企業をいくつか知っていますが、顧客は1位になると主張しました。非常に陽気でした。エンジニアは実際にフロントエンドコードを次のように変更する必要がありました。if (cust == 345681) print(1);

    交通機関については、複合を選択します PackageID + Port+time。これはもう少し面白いです。 代理を作成できたはずです ここでも同様に機能します。

    しかし、ここにインデックス作成の魔法があります。主キーは自動的にインデックスを取得します。つまり、検索は主キーよりもはるかに効率的です。

    このデータベースを検索する場合、ほとんどのクエリは「このパッケージはどこにありますか?」という形式になります。つまり、このPackageIDを指定して、現在のポートと時刻を教えてください。主キーの一部としてPackageIDがない場合は、PackageIDよりも追加のインデックスが必要になります。

    これはいいですね。最後のステップとして、これら3つのテーブルをSQLで定義しましょう。構文は、使用しているデータベースによってわずかに異なります。

    MySQLでの主キーの定義

    CREATE TABLE customers
    ( customerID  INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY,
      last_name   VARCHAR(30) NOT NULL,
      first_name  VARCHAR(25) NOT NULL,
      email		  VARCHAR(50) NOT NULL,
      address     VARCHAR(300)
    );
    CREATE TABLE packages
    ( packageID  INT(15) NOT NULL AUTO_INCREMENT,
      weight     DECIMAL (10, 2) NOT NULL,
      content    VARCHAR(50),
      CONSTRAINT packages_pk PRIMARY KEY (packageID) # An alternative way to above,
      # when you want to name the constraint as well.
    );
    CREATE TABLE transportation
    ( package 	INT(15) NOT NULL,
      port  	INT(15) NOT NULL,
      time	 	DATE NOT NULL,
      
      PRIMARY KEY (package, port, time),
      FOREIGN KEY package
      	REFERENCES packages(packageID)
    	ON DELETE RESTRICT    # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
    
    );

    PostgreSQLでの主キーの定義

    CREATE TABLE customers
    ( customerID  SERIAL NOT NULL PRIMARY KEY, # In PostgreSQL SERIAL is same as AUTO_INCREMENT - it adds 1 to every new row.
      last_name   VARCHAR(30) NOT NULL,
      first_name  VARCHAR(25) NOT NULL,
      address     TEXT,
      email		  VARCHAR(50) NOT NULL
    );
    CREATE TABLE packages
    ( packageID  SERIAL NOT NULL,
      weight     NUMERIC NOT NULL,
      content    TEXT,
      CONSTRAINT packages_pk PRIMARY KEY (packageID) # In PostgreSQL, this alternative way works too.
    );
    CREATE TABLE transportation
    ( package 	INTEGER NOT NULL,
      port  	INT(15) NOT NULL,
      time	 	DATE NOT NULL,
      
      PRIMARY KEY (package, port, time),
      
      FOREIGN KEY package
      	REFERENCES packages(packageID)
    	ON DELETE RESTRICT    # It's good practice to define what should happen on deletion. In this case, I don't want things to get deleted.
    
    );

    それほど違いはありませんね。基本を理解したら、ドキュメントをざっと見るだけで、ほとんどすべてのデータベースに適用できます。重要なのは、何を探すべきかを知ることです!

    頑張って、若いパダワン。

    これを楽しんだ?シニアソフトウェアエンジニアから学んだこともお気に召すかもしれません



    1. OracleでサポートされているROUND()およびTRUNC()日付関数のフォーマットモデル

    2. LIKEと〜の代わりに、代替との正規表現の一致を行うときにSIMILARTOのみが機能するのはなぜですか

    3. SQLでテーブルと列を削除する方法

    4. 結合とサブクエリ