1.1 はじめに
データベースの設計は、Java プロジェクトのアーキテクチャの設計に似ています。すべてのデータを 2 つのテーブルに配置することも、スキーマと多数のテーブルから美しいデータ構造を構築することもできます。
開発者がデータベースを設計するときに通常直面するタスクは次のとおりです。
- 必要な情報がすべてデータベースに保存されていることを確認します。
- 必要なすべてのリクエストに関するデータを取得できるようにする。
- データの冗長性と重複を削減します。
- データベースの整合性の確保
- データアクセス速度の最適化
覚えておくべき主な点は、理想的なデータベース構造を作成することはできないということです。コードと同様に、これも常に変更されます。データベース構造を設計する際には、次の 3 つの点に留意する必要があります。
- 構造は十分に優れている必要があります。
- 他人が理解できるものにはすべて論理がなければなりません。
- 時期尚早な最適化は諸悪の根源です。
世界最高のデータベース構造を作る必要はありません。彼女はまだまだ変わります。あなたの仕事は、データベースの構造を 20 回変更した後でも、それを十分に簡単に理解できるようにすることです。
おそらく、仕事を始めて最初の数年間は、あなたがゼロからベースを設計することを誰も信頼しないでしょう。既存のスキーマに変更を加えます。どのような原則に基づいて配置されているかを理解し、それらを遵守するように努める必要があります。彼らの憲章により、彼らは他人の修道院に登ることはありません。
必要になるまでデータベースを最適化しないでください。テーブルに数百行しかない場合、DBMS はそれをメモリ内に保持し、クエリをキャッシュします。
一方で、重要なリクエストの処理は数十倍、さらには数百倍も高速化できるはずです。そして、その方法を知っていれば良いでしょう。高校1年生って何て言うんですか?「学校で教えられたことはすべて忘れてください...」
データベースの正規化が何であるかをご存知の場合は、急いで喜んでいただきたいと思います。おそらく、仕事で非正規化を扱うことになるでしょう。プロジェクトの聖域にとって、データベースの速度ほど重要なものはありません。また、データベースからのデータの選択を高速化するために、200 (!) のテーブルを (驚異的な冗長性で) 1 つに結合する必要がある場合は、これを行う必要があります。
1.2 ライブラリの設計
この主題領域に少し踏み込んで、典型的な書籍ライブラリと同じくらい単純なものを使用してデータベース設計について考えてみましょう。
図書館の主な仕事は図書基金の処理です。システム ユーザーの 3 つの主要なグループ (読者、図書館員、管理者)を区別するのは簡単です。それぞれのアクティビティをユースケース図に示します。
![](https://cdn.codegym.cc/images/article/ce739b07-800a-4e3c-a436-b40d3c54ea1d/512.jpeg)
すでに、将来のデータベースのいくつかのエンティティと関係を区別できます。
![](https://cdn.codegym.cc/images/article/b7373320-28d3-4fd8-9b62-a75c6102299f/1024.jpeg)
このアプローチでは、読者と本をどのように結び付けるかが明確ではありません(読者は「発行/受け取り」の関係にアリティを持ちません。本が複数部ある場合、それは複数の読者に発行される可能性があります。本が 1 部として理解される場合、現在の読者の本の一覧表に保存されたときに、誰が (そして何回) この本を以前に手に取ったのかについての情報を取得することは不可能になります。
解決策は、書籍を発行するためのカードという追加のエンティティを導入することかもしれません。本を読者に渡すときにカードが作成され、本を渡すときに対応するマークが付けられます。これらのカードの助けを借りて、各ユーザーの借金が特定され、本の使用に関する統計が計算されます。読者が書籍を予約するとカードも起動し、予約した書籍が一定期間内に読者に取られなかった場合、カードは破棄される。読者が予約できる本の数には制限があります。
文献を選択するとき、ユーザーは著者、タイトル、出版年によって検索結果をフィルタリングできる機能を備えた文献カタログを表示します。
図書館内のすべての書籍の統計と、一定期間の書籍の発行部数を計算することができます。計算が実行されるブック インスタンスの最小数を設定することもできます。これらの統計に基づいて、未使用の本は図書館から償却されます。
対象領域の主なエンティティは次のように区別できます。
- ユーザー(図書館員および管理者)。
- 読者;
- 読書室。
- 本;
- 図書発行カード。
- 本の予約カード。
データベースの修正された ER 図を図に示します。
![](https://cdn.codegym.cc/images/article/af26b62d-dd9e-4713-be71-3f4fc10c5379/1024.jpeg)
図 1 に示す使用例によれば、データベースは次のクエリを実装する必要があります (完全なリストではありません)。
- 指定した条件に一致する書籍を表示します。
- 時間通りに閉まらなかった本を発行するためのカードを持っているユーザーを表示します (図書館員は債務者を探しています)。
- 指定されたユーザーの図書貸出カードに対応する、期限内に閉まらなかったすべての本を表示します (ユーザーは新しい本を求めて図書館に来ました。彼が債務者であるかどうかを確認し、そのことを彼に知らせる必要があります)。
- N 秒以上前に作成されたすべての予約カードを削除します。
- 指定されたユーザーの未封書予約カードに対応するすべての書籍を表示します (読者は本を注文し、そのために図書館に来ました。図書館員は、配付するためにこのリストを取得する必要があります)。
1.3 スキーマの形成
データ スキーマを形成するには、まずエンティティの詳細を ER 図に追加する (改良する) 必要があります。同時に、ER 図の構築中にエラーが見つかることもあります。このタスクでは、本が図書館ホールと「何らかの形で」接続されている必要があることがわかりました。
これは、必要な「ホール番号」を書籍に記載することで実現できますが、このアプローチでは、同じ書籍をデータベースに何度も記述する必要があります (異なるホールで発生した場合)。より正しいアプローチは、追加のエンティティ「本の配置」を導入することです。この図は、エンティティとプロパティが追加された ER 図を示しています。
![](https://cdn.codegym.cc/images/article/e0d1296a-18db-464c-88ac-c6f6a33c661b/1024.jpeg)
上の ER 図は主要なテーブル、関係、属性を反映しており、これに基づいてデータベース モデルを構築できます。ER 図には標準はありませんが、多くの表記法 (Chen、IDEFIX、Martin など) がありますが、ドメイン モデルについては標準も表記法も見つかりませんでした。ただし、このような図を作成する過程では、キー フィールド (外部および内部) が必然的に強調表示され、場合によってはインデックスやデータ型が強調表示されます。
この場合、次の図のようになります。
- リンクについては、Martin の表記法 (「カラスの足跡」が使用されます)。
- テーブルは、3 つのセクションに分割された長方形として表示されます。
- テーブル名;
- 内部キー (マーカーでマーク);
- 残りのフィールドはマーカーでマークされていますが、必須フィールドはマーカーでマークされています。
このモデルを開発するとき、administrators テーブルを librarians テーブルと結合し、users テーブルを追加したいという要望がありました。ただし、次のようになります。
- 管理者は特定のルームに関連付けられていません (対応するフィールドに null 値を入力する必要があります)。
- これにより、おそらくアクセス権の配布が複雑になります。現在、データベース管理者 (特別な DBMS パネルを使用して作業し、開発中のシステムにアカウントを持っていない) のみが管理者テーブルにアクセスできます。ただし、テーブルを結合する場合、ユーザー クエリは新しいテーブルにアクセスする必要があります。
この図を作成するときに、ER 図の欠陥が見つかり、修正されました。図書館員とホールを統合する表が追加されましたlibrarians_rooms
。これは、1 人の図書館員が複数の部屋で作業できる一方で、複数の図書館員が同じ部屋で作業できるため必要です。
データベースを設計するときは、少なくとも上記の例のように推論できる必要があります。成功したと思われる場合は、さらに理論を進めてみましょう。
GO TO FULL VERSION