東方算程譚

Oriental Code Talk ── επιστημηが与太をこく、弾幕とは無縁のシロモノ。

目次

Blog 利用状況

ニュース

著作とお薦めの品々は

著作とお薦めの品々は
東方熱帯林へ。

あわせて読みたい

わんくま

  1. 東京勉強会#2
    C++/CLI カクテル・レシピ
  2. 東京勉強会#3
    template vs. generics
  3. 大阪勉強会#6
    C++むかしばなし
  4. 東京勉強会#7
    C++むかしばなし
  5. 東京勉強会#8
    STL/CLRによるGeneric Programming
  6. TechEd 2007 @YOKOHAMA
    C++・C++/CLI・C# 適材適所
  7. 東京勉強会#14
    Making of BOF
  8. 東京勉強会#15
    状態遷移
  9. 名古屋勉強会#2
    WinUnit - お気楽お手軽UnitTest

CodeZine

  1. Cで実現する「ぷちオブジェクト指向」
  2. CUnitによるテスト駆動開発
  3. SQLiteで組み込みDB体験(2007年版)
  4. C++/CLIによるCライブラリの.NET化
  5. C# 1.1からC# 3.0まで~言語仕様の進化
  6. BoostでC++0xのライブラリ「TR1」を先取りしよう (1)
  7. BoostでC++0xのライブラリ「TR1」を先取りしよう (2)
  8. BoostでC++0xのライブラリ「TR1」を先取りしよう (3)
  9. BoostでC++0xのライブラリ「TR1」を先取りしよう (4)
  10. BoostでC++0xのライブラリ「TR1」を先取りしよう (5)
  11. C/C++に対応した、もうひとつのUnitTestFramework ─ WinUnit
  12. SQLiteで"おこづかいちょう"
  13. STL/CLRツアーガイド
  14. マージ・ソート : 巨大データのソート法
  15. ヒープソートのアルゴリズム
  16. C++0xの新機能「ラムダ式」を次期Visual Studioでいち早く試す
  17. .NETでマンデルブロ集合を描く
  18. .NETでマンデルブロ集合を描く(後日談)
  19. C++/CLI : とある文字列の相互変換(コンバージョン)
  20. インテルTBBによる選択ソートの高速化
  21. インテルTBB3.0 によるパイプライン処理
  22. Visual C++ 2010に追加されたSTLアルゴリズム
  23. Visual C++ 2010に追加されたSTLコンテナ「forward_list」
  24. shared_ptrによるObserverパターンの実装
  25. .NETでマンデルブロ集合を描く(番外編) ── OpenCLで超並列コンピューティング
  26. StateパターンでCSVを読む
  27. 状態遷移表からStateパターンを自動生成する
  28. 「ソートも、サーチも、あるんだよ」~標準C++ライブラリにみるアルゴリズムの面白さ
  29. インテルTBBの同期メカニズム
  30. なぜsetを使っちゃいけないの?
  31. WPFアプリケーションで腕試し ~C++でもWPFアプリを
  32. C++11 : スレッド・ライブラリひとめぐり
  33. Google製のC++ Unit Test Framework「Google Test」を使ってみる
  34. メールでデータベースを更新するココロミ
  35. Visitorパターンで遊んでみたよ
  36. Collection 2題:「WPFにバインドできる辞書」と「重複を許す検索set」
  37. Visual C++ 2012:stateless-lambdaとSQLiteのぷち拡張
  38. 「Visual C++ Compiler November 2012 CTP」で追加された6つの新機能

@IT

  1. Vista時代のVisual C++の流儀(前編)Vista到来。既存C/C++資産の.NET化を始めよう!
  2. Vista時代のVisual C++の流儀(中編)MFCから.NETへの実践的移行計画
  3. Vista時代のVisual C++の流儀(後編) STL/CLRによるDocument/Viewアーキテクチャ
  4. C++開発者のための単体テスト入門 第1回 C++開発者の皆さん。テスト、ちゃんとしていますか?
  5. C++開発者のための単体テスト入門 第2回 C++アプリケーションの効率的なテスト手法(CppUnit編)
  6. C++開発者のための単体テスト入門 第3回 C++アプリケーションの効率的なテスト手法(NUnit編)

AWARDS


Microsoft MVP
for Visual Developer - Visual C++


Wankuma MVP
for いぢわる C++


Nyantora MVP
for こくまろ中国茶

Xbox

Links

記事カテゴリ

書庫

日記カテゴリ

DBわからん、やっぱわからん

...定石とかそんなものを知らんから、なんだろか。

今書いてるお試しアプリでは、ポリモーフィックな木構造を扱います。

class 部品; // 森羅万象のルート
class 基板 : 部品; // 基板(部品の集合)もまた部品なり
class 抵抗 : 部品; // 抵抗値をメンバに持つ
class コンデンサ : 部品; // キャパシタンスをメンバに持つ
class コイル : 部品; // インダクタンスをメンバに持つ

こんなカンジのクラス群。これのインスタンスを使って:

製品 は 基板1 から構成される
基板1 は 抵抗1, 抵抗2, 基板2, 基板3  から構成される
基板2 は 抵抗3, コイル1 から構成される
基板3 は コイル2, コンデンサ1 から構成される

なんてな木構造を構築するっす。
で、こいつをDBに書いたり/DBから読んだり せぇと。

こんなとき、クラスごとのテーブル作るんですよね。
 基板table ( ID TEXT, タテ幅 INTEGER, ヨコ幅 INTEGER)
 抵抗table ( ID TEXT, 抵抗値 INTEGER)
 コンデンサtable ( ID TEXT, キャパシタンス INTEGER)
 コイルtable ( ID TEXT, インダクタンス INTEGER)
みたいな。 # [1] ここまであってる?


で、製品を構成する要素をテーブルにすると
構成要素table (
 ID TEXT, ← 部品のID
  PARENT TEXT ← その部品が乗ってる部品。なければNULL
)

これで製品を構成する全要素を構成要素tableに載せられます
# [2] ここまであってる?

製品:
(基板1, NULL)
(基板2, 基板1)
(抵抗1, 基板2)
(抵抗2, 基板2)
...

この製品を構成する抵抗1の抵抗値が知りたいとき、
SELECT 抵抗値 FROM 抵抗table WHERE ID=抵抗1
なのかな。
# [3] ここまであってる?

でもね、「抵抗tableを検索すればいい」ってこと、つまり
部品のクラスを示す"型コード"を構成要素tableのカラムに
置かにゃならんですよね。
# [4] ここまであってる?

だとすると"型コード"から"対応するテーブル名"を導出できにゃ
あかんですよね?
# [5] ここまであってる?

[6] そう、コードの中では仮想関数でやってたよなことです。
それをDB上にマップするのってどぉやんです?

投稿日時 : 2008年4月8日 13:59

コメントを追加

# re: DBわからん、やっぱわからん 2008/04/08 14:18 ひろえむ

方法や用途にもよりますが、この情報からですと・・・・

部品   (parts_id, parts_name) pk(parts_id)
部品明細 (parts_id, parts_detail_id, index, value) pk(parts_id, parts_detail_id, index)

って感じでしょうか。

明細の意味や名称がほしい場合は、それらをマスタ化するって感じでしょうか・・・。

部品マスタ   (parts_id, parts_name) pk(parts_id)
部品明細マスタ (parts_id, parts_detail_id, parts_detail_name) pk(parts_id, parts_detail_id)

ここに「抵抗値」であったり「たて幅」「よこ幅」なんかの文字情報を格納しておく・・・って感じでしょうか。

まぁ、利用用途にもよるので、これが正解ってのもないのは、クラス設計と同様ですね(^^;

もっといい方法もあるのかもしれませんが単純な感じでこんな感じで正規化するかなぁ・・・(^^;

# re: DBわからん、やっぱわからん 2008/04/08 14:19 ひろえむ

部品マスタがあったら、部品テーブルはいらないか(^^;;;;

# re: DBわからん、やっぱわからん 2008/04/08 14:27 ひろえむ

まとめ直すと・・・

トランザクションテーブル
・部品明細テーブル
(parts_id, parts_detail_id, index, value)
 parts_id    : 部品ID[Key]
 parts_detail_id : 部品明細ID[Key]
 index      : 部品id, 部品明細id単位の連番[Key]
 value      : 値

マスタテーブル
・部品マスタ
(parts_id, parts_name)
 parts_id    : 部品ID[Key]
 parts_name   : 部品名

・部品明細マスタ
(parts_id, parts_detail_id, parts_detail_name)
 parts_id     : 部品ID[Key]
 parts_detail_id  : 部品明細ID[Key]
 parts_detail_name : 部品明細名

こんな感じでしょうか(^^;
もっといい方法があるかもしれません(^^;;;

# re: DBわからん、やっぱわからん 2008/04/08 14:29 はつね

それぞれの部品ごとにテーブル作らない方がいいですね。
なので[1]の時点を見直す方が良いです。

部品マスタを作って、そこにスペックを格納する感じ。
物理的なサイズとか共通欄はNOT NULLにして、部品固有の情報はNULL項目にするか、それこそ、ここで部品ごとのテーブルに分解とかね。

# re: DBわからん、やっぱわからん 2008/04/08 14:39 十郎

はじめてコメントさせて頂きます<(_ _)>

部品(parts_id, 型コード)
基板(parts_id, タテ幅, ヨコ幅)
抵抗(parts_id, 抵抗値)
コンデンサ(parts_id, キャパシタンス)
コイル(parts_id, インダクタンス)
構成要素(partent_parts_id, child_parts_id)

似たような案件をやっているのですが、
私ところはこんな感じのDB設計にしました。
合っているのかどうかは自分でもわかりません・・・

構成要素から追っていく場合に、
構成要素 -> 部品 -> 部品の型コードで判断して、
データを持ってくるのが面倒なのかなと思ったりもしています。

# re: DBわからん、やっぱわからん 2008/04/08 14:40 はつね

> 部品マスタのスキーマ
新しい部品が出てきたときに新しいスペックが追加されるなら列追加とかになるかと。もしくは備考欄にXMLデータとしていれるか、そもそもとしてスペック欄をXMLデータとして1欄で済ませてしまうかとか。
このあたりは業務要件と相談です。

# re: DBわからん、やっぱわからん 2008/04/08 14:41 επιστημη

> 部品マスタを作って、そこにスペックを格納する感じ。

なるほど。
でもさ、部品の種類によって必要となるフィールドの名前と型が多岐にわたり、さらに将来どんな部品が追加されるか予測できないとした場合、あらかじめ全部品を想定した部品マスタのスキーマが起こせないんちゃいます? そんときゃどーすんです?

部品ごとにテーブル作るんなら、新たな部品が追加になってもおっけぃなんかなー、と。

> それこそ、ここで部品ごとのテーブルに分解とかね。

ここで同じ問題に遭遇せんのでしょうか。
つまり"部品の種類"フィールドにある値と"それが格納されたテーブルの名前"との対応表はどこにあってどうやって引き当てるんだろ...

# re: DBわからん、やっぱわからん 2008/04/08 14:47 凪瀬

つくづく思うけど、RDBMSって拡張には弱いですよね…。
いつも顧客要望を載せるのに苦労する。

# re: DBわからん、やっぱわからん 2008/04/08 14:48 επιστημη

ごめん初音さん、書き足りんのに気づいて削除してるうちレス付いてもた。

業務用件次第なのは百も承知です。

なんてんだろ、僕は日常ポリモーフィックなオブジェクトの世界をコードで表現してるんだけど、このポリモーフィックな世界とDB界の"表"との対応をどうつけるのか、まだもやもやーっとしてるす。

追加分はXMLか...わかるんですけど、森羅万象を四角い表で表現しようっていうRelationalDBの美しい世界からは逸脱しちゃうんですよねぇ。

# re: DBわからん、やっぱわからん 2008/04/08 14:54 十郎

追記です
>だとすると"型コード"から"対応するテーブル名"を導出できにゃあかんですよね?
ですが、
ここでいう、基板とか抵抗とかコンデンサとかコイルとかをUnionしたViewを作って、
構成要素 (left join) View
みたいにすると、型コードを意識せず、
SQL文で一発で取得できると思います。

# re: DBわからん、やっぱわからん 2008/04/08 14:56 えムナウ

こういうときのDB設計の教科書には「強実体・弱実体・関連」というキーワードです。

部品テーブルという強実体を作成します。
ID int key
部品CD ntext
部品種別ID int

部品種別テーブル
ID int key
部品種別名 ntext
関連テーブル名 ntext

抵抗テーブルという弱実体を作ります。
ID int key
抵抗値 int

抵抗関連テーブルという関連を作ります。
ID int key
部品ID int
抵抗ID int

実装関連テーブルという関連を作ります。
ID int key
実装先部品ID int
実装部品ID int

教科書ではなのでテーブル数が多いです。
正規化をちゃんとしているからなのですが・・・

# re: DBわからん、やっぱわからん 2008/04/08 14:59 はつね

ポリモーフィックなオブジェクトとリレーショナルな世界って相性悪そう。リレーショナルな世界で多様性を持たせようとすると十郎さんがかかれているようにUNIONとか使う事になるのかな。

# re: DBわからん、やっぱわからん 2008/04/08 15:06 えムナウ

抵抗テーブル・抵抗関連テーブルは基板・抵抗・コンデンサ・コイルと何種類も必要になります。

この一段階前の正規化時点では、
部品詳細テーブル
ID int key
抵抗値 int null
タテ幅 int null
ヨコ幅 int null
キャパシタンス int null (intでいいのか?)
インダクタンス int null (intでいいのか?)

部品詳細関連テーブル
ID int key
部品ID int
部品詳細ID int

こんな状態ですのでこちらを使ってもいいかもしれません。

# re: DBわからん、やっぱわからん 2008/04/08 15:13 えムナウ

ちなみに強実体はデータの大元です。
弱実体は強実体の詳細や付属情報を管理するテーブルです。
関連テーブルは強実体と弱実体を結ぶテーブルです。
関連テーブルは1対1が保証できる範囲においては弱実体に強実体のIDを記述することで省略できます。

# re: DBわからん、やっぱわからん 2008/04/08 15:14 επιστημη

そだそだ、
「データベースでオブジェクト指向」をネタに
勉強会でいっちょ喋ってくだちぃ > えらいひと

オブジェクト指向に基づくデータの表現、すなわち抽象化はおいといて継承/委譲/多態モロモロを表で表現できるのか、どう表現するのか、表現できないものはあるのか、その代替案はあるのか、などなどなど。

オーディエンスはDBわからんちんのεπιστημηを想定してください。わかってんのは"タテ/ヨコの四角い表の集合である"ことと、"カラムを使って表を繋ぐことができる"ことダケです (^^;;;;;

# re: DBわからん、やっぱわからん 2008/04/08 15:18 はつね

「データベースでオブジェクト指向」っていうとOODBとかになってしまうので「ER図でオブジェクト指向」とか「RDBMSでオブジェクト指向」とかですかね~。

# re: DBわからん、やっぱわからん 2008/04/08 15:23 επιστημη

ですね。あくまでシック(?)な四角い表でオブジェクト指向が実現できるんか!? について。

# あ、そーいや「MVP受賞記念公演」がまだですよぅ♪

# re: DBわからん、やっぱわからん 2008/04/08 15:59 凪瀬

RDBMS「を」OOP対応に拡張することなら以前に考えているけど…
http://blogs.wankuma.com/nagise/archive/2007/11/20/109331.aspx

アレですか、C言語でOOPを表現するような感じで
言語など環境でサポートされていない状況下でどうやってOOPやるかって話ですな。

# re: DBわからん、やっぱわからん 2008/04/08 16:06 επιστημη

たぶん(?)そう。ポリモーフィックな木の世界を僕はひょいひょいこしらえてたとこに「それをDBに置いてくんない?」って言われてアタマ抱えたのですよ。この両者は自然にマッピングできんだろか? って。

# RDBMSにオブジェクト指向を導入できるのか? 2008/04/08 16:21 凪瀬 Blog

RDBMSにオブジェクト指向を導入できるのか?

# re: DBわからん、やっぱわからん 2008/04/08 17:38 はつね

>「MVP受賞記念公演」がまだですよぅ♪

もう語りつくされている気がするので、他のネタにしますね~(あーよかった)♪

# re: DBわからん、やっぱわからん 2008/04/08 18:17 biac

マーチン・ファウラーのアナリシスパターンに出てくる、 知識レベルと操作レベルを分ける話が、 ひょっとすると近いのかも f(^^;

知識レベル
 部品型   部品特性型   特性単位
 ----- ------- ----
 基板    タテ      mm
 抵抗    ヨコ      Ω
 コンデンサ 抵抗値     F
 コイル   静電容量    H
       インダクタンス 
※実際には、それぞれ ID 列も持つ。

操作レべル
 ・製品テーブル
 製品ID 構成ID
 --- ---
  0   1

 ・構成要素テーブル
 構成ID 部品ID 数量 親ID *備考
 --- --- -- --
  1   11    1  NULL *基板1
  2   12    1  1 *基板2
  3   13    3  2 *抵抗1
  4   14    2  1 *抵抗2、基板1に乗る
  5   14    5  2 *抵抗2、基板2に乗る

 ・部品テーブル
 部品ID 部品型 呼称
 --- --- ---
 11   基板  基板1
 12   基板  基板2
 13   抵抗  抵抗1
 14   抵抗  抵抗2

 ・部品特性テーブル
 特性ID 部品ID 部品特性型 値  特性単位
 --- --- ----- -- ----
 21   13   抵抗値    120 Ω
 22   12   タテ     300 mm
 23   12   ヨコ     450 mm

※こんなん実装したらレスポンスがどうなっちゃうか怖くて、試してみたこともないですけど f(^^;

# re: DBわからん、やっぱわからん 2008/04/08 18:19 biac

あ、 上の 部品型、 部品特性型、 特性単位 ってのは、 3つのテーブルです。

# re: DBわからん、やっぱわからん 2008/04/09 0:16 片桐

データの塊の概念をデータベースにするってのは、つまり、一旦思いっきり抽象化しまくって似たモン全部一緒くたにしてから均して、ダブる情報をマスターにきりわけて正規化して……やと思うねん。

せやから、うちの思った形はひろえむさんのに近い(笑)

# re: DBわからん、やっぱわからん 2008/04/09 12:55 HiJun

テーブルの結合結果をViewにしてまうとか...
でも更新が...

タイトル
名前
URL
コメント