2009-05-28 30 views
1

私は現在、サイトのアイデアのためにいくつかのものを使いこなしています。ユーザーがデータを保持している「テーブル」を作成し、このデータをクエリできるようにしたいと思っています。 SQLクエリを書くとうまくいけば、Excelを使用するより簡単に)。SQLの "動的"テーブル?

これまで私の考えでは、データベース内にいくつかのテーブルを使用して表現しています。テーブルを表すテーブルが1つ、テーブルの列を表すテーブルが1つ、テーブルの各行を表すテーブルが1つ、 1つは値を表します。 (擬似SQL)に似て何か:

CREATE TABLE 'Tables' (
    Id INT NOT NULL PRIMARY KEY, 
    NAME VARCHAR(255) 
) 

CREATE TABLE 'TableColumns' (
    Id INT NOT NULL PRIMARY KEY, 
    TableId INT NOT NULL FOREIGN KEY ON 'Tables', 
    NAME VARCHAR(255) 
) 

CREATE TABLE 'TableRows' (
    Id INT NOT NULL PRIMARY KEY, 
    TableId INT NOT NULL FOREIGN KEY ON 'Tables', 
    RowNumber INT NOT NULL 
) 

CREATE TABLE 'TableValues' (
    RowId INT NOT NULL PRIMARY KEY, 
    ColumnId INT NOT NULL PRIMARY KEY, 
    Value VARCHAR(255) 
) 

(つまり私の事実とあまり気にしないでください、TableValuesテーブルがここ2つの、主キーのフィールドがあり、「複合」の主キーを表すことになっていますのでご注意構文は法的なSQLではない、それはちょうどアイデアを示すことになっている)。

これで少しのテストを行い、単純なクエリ(単純なフィルタリング、順序付けなど)を正常に実行できました。これを行う私のやり方は、まずTableRowsテーブルを照会することでした。フィルタリングのために、カラムが基準と一致しないローをフィルタリングしました。ソートのためにカラムの内容に基づいてRowIdsをソートしました。必要なものを選択するだけで、ここから希望の順序で行IDのリストが作成されました。

これはすべて問題なく動作しますが、ここから少し離れています。私はどうにかして(実際には私の主な問題である)異なるデータ型を表現することができますし、後で結合を行う方法を理解することもできます。

私はこれを行うより良い方法があるかどうか疑問に思っています。もちろん、ここでのパフォーマンスは重要な要素ですが、私は仮想テーブルごとに数十万行、おそらく約1000行の仮想テーブルをサポートするつもりはないことを覚えておいてください。もちろん、システム全体では多くのこれら。

これは、SQLクエリを使用して同様にクエリを実行するためにC#で作成されたクエリを使用してデータベースにテーブルを作成することができますが、ユーザーに "構築"このように私のデータベースに対してクエリを実行すると、それは多くのバグが現れるようなパスを導くかのように思えます。最悪のシナリオでは、ユーザーが一方向または他の方法でデータベースを強制終了できるようになります。

また、私の問題は、これをC#の観点から理解できる方法で処理する方法になります。これまでのところ、私はLINQの使用に慣れていて、必要な機能を適用する独自の拡張メソッドを作成すると思います。つまりExtensionMethodsがIQueryableを拡張しています。

これは、どのようにこれを行うことができるか、パフォーマンスを調整するアイデア、テーブルの別々のデータ型を扱う方法のアイデアです(もちろん、テーブルの列に型を格納します実際に値を格納して、フィルタリング、並べ替えなどを行うことができますか?テーブルのテーブルに「TextValue」、「MoneyValue」などの列を追加するだけでなく)。最後に、ここでいくつかの良い議論ができればと思っています。私は少なくともこれをやや面白い話題と考えています。

+14

私はこれをhttp://www.thedailywtf.comに送るインセンティブとして投票しています。 – TheTXI

+1

TheTXIによれば、この種の「スキーマ」は毎日のWTFで常に見られます。それは信じられないほど悪い考えです。そして陽気。 – Welbog

+1

私はこれが悪いスキーマであるというアイデアを持っていました。アイデアを改善する方法についていくつかのアイデアを得るために、私はここに投稿しました。このようなやり方で行われているかどうかではなく、私が達成できるものを気にしています。そしてまた、私は学習を気にします:)。 – kastermester

答えて

9

に答えるのをdsteeleすることはかなり(非常に)似ていると思うなど、彼らはうまくページに収まるように、あなたのタプルを合わせ、VARCHAR上

をCHARを使用すると、誰もがいくつかのポイントまたは別の時にそのアイデアに出会います。

これは正しく動作するはずです。

です。並べ替え

TheDailyWTFについてのコメントにはポイントがあります。 DBMSの上にDBMSを再実装するのは良い考えではありません。そのようなつもりはメタはあなたが本当に(あなたが?)、柔軟性のようなものを必要な場合はunderperfomingシステム

  • メンテナンスの悪夢
  • あなた

    • を与えるために起こっている、あなたの時間がはるかに良いだろういくつかのテーブルにメタデータを格納し、データベース内の実際のテーブルのスキーマを生成するためのレイヤーの実装に費やしました。

      私の知っているこの種のシステムのいくつかの例があります。

      • Microsoft OSLO(特にリポジトリシステム)
      • ASAM-ODSサーバアーキテクチャは
      • (ASAM-ODSパッケージを探してください)

      他にもあると思います。

      あなたのデータベースは実際には最後に意味があり、RDBMSを強く使用しています。また、テーブルが作成されると、そのような設定が常に行われるべきではないため、必要に応じて(主にインデックス作成という点で)データベースを微調整することができます。

      私は実際にあなたが提案するシステムの種類に唯一正しい答えがではないと感じてです。

    +0

    ありがとう、私はそれを調べます:)。 – kastermester

    +0

    こんにちはDenis、私はASAMについていくつか質問したいと思います。私のために少し時間があるなら、それはいいでしょう。 [ASAM室](http://chat.stackoverflow.com/rooms/81001/asam)に参加することをためらってください –

    2

    downvotesの危険性があるので、なぜMS Accessをインストールしてみませんか?

    +1

    これは、デスクトップアプリケーションではなくウェブアプリケーションを意図しています。なぜ、人々にMS Accessを使用するように指示するウェブページを作成しないのですか? - 私のお母さんはそうではないので、私の妹はそうではありません。正直なところ、私が知っている人はいません。 – kastermester

    +2

    @kastermester:それから私はそれらをGoogleドキュメントに送信します。 – GEOCHET

    +2

    @kaster:十分に公正ですが、誰かがあなたのためにより良い答えを出すのを助けるかもしれないので、私はとにかく私の答えを保持します。 – belgariontheking

    1

    MicrosoftのBusiness Contact Managerアドインfor Outlookでこのようなアプローチを実行しました。フィールド型を扱う方法は、各フィールドの型を定義するテーブルを持つことです。次に、Varbinary列だけを含むテーブルに実際のフィールド値を格納します。 varbinaryへの/からの変換は、フィールドタイプテーブルによって制御されます。

    1

    私はすべての嫌悪感と誰も実際にあなたの質問に答えようとしている理由はわかりません。たとえそれが最終的に「どのようにGoogle Docsを実装しますか」という質問であっても、それはまだまだ公正な問題です。 (私はすべての憎悪を約あると仮定しています何を)あなたは本当にこれを実行するかどうかを経由思っていると仮定すると、

    は、ここでは、少なくとも、より良いアイデアです:

    DATA_TABLE { 
        TABLEID INT, 
        INT1 INT, 
        INT2 INT, 
        VARCHAR1 VARCHAR(255), 
        ... etc 
    } 
    

    は、メタデータは、ことをどこかに保存されています特定のTABLEIDの名前、使用されているフィールド、ユーザが使用している名前などが記録されます。ジョインは、データテーブル上での自己ジョインだけなので、サポートが簡単です。メタデータをデータベースに保存するかどうかは、あなた次第です。

    このアプローチは完全にうまく動作します(この種のスキーマを使用した多くの成功した.comサイト、私が関与していた人や知っていた人の両方を知っています)が、私は、これはいくつかの理由について

    +0

    ありがとうございました。興味深く有望なアイデアのようです。私はそれを調べます。 – kastermester

    +0

    すべてのデザインにトレードオフがあることは注目に値する。他の人はテーブルを作成するよう提案しました。ユーザーごとにスキーマ/ユーザーを作成しない限り、命名の競合が発生します。どのくらいの(古くなった)ユーザーとテーブルに依存するかによって、すべてのデザインに関連するメンテナンス費用があります – Matt

    +0

    私はこの回答を理解できませんか?すべてが私のdata_tableにマップされている場合、ユーザー/ユースケースごとにdata_tableを推奨しているのでなければ、私の持つフィールド数、タイプなどを知るにはどうすればいいですか? –

    6

    これは興味深い考えですが、このようにSQLを使用することは、おそらく時間の経過とともに非常に苦しくなるでしょう。
    私が正しくお答えいただければ、ユーザーはデータ構造を定義し、それらの構造にデータを保存することができます。あなたはまたそれを照会できるようにしたい。 これについては別の方法が考えられます。

    • XMLの使用はどうですか?各ユーザーがXMLファイルを "テーブル"ごとに保存し、そのスキーマを維持するだけです。各「行」は、子要素を持つXML要素です。オプションでXMLをSQLに張ったり、他の手段で格納することもできます。これは大規模なデータセットではうまく機能しませんが、何千ものレコードでは驚くほど高速です。私はC + +で20 + MBのXMLファイルでいくつかのテストを行い、それらを作成し、それらを読み取り、1秒未満でそれらを解析することができました。 LINQ to XMLを使用すると、かなり洗練されたクエリと結合を作成することさえできます。大規模なエンタープライズシステムにはXMLを使用しませんが、メモリや高速プロセッサを搭載した最新のマシンにはどれだけの距離があるのでしょうか?それは無限に柔軟です。
    • 代わりにオブジェクト指向データベース(Matisseなど)を使用できますか?私は自分自身の経験は持っていませんが、XMLアプローチのように、より良いパフォーマンスで簡単に実行できると思います。
    • Amazon Simple DB:私が正しく覚えていれば、これは本質的にあなたが使用できる名前/値のペアベースのデータベースです。あなたのアプリケーションでは、代わりにバックグラウンドでそれを使用して、すべての配管工事に対処する必要はありませんか? SQL Serverの料金を払わなければならない場合、Amazon DBは安価で大規模になりますが、リレーショナルクエリのようなものはありません。
    +0

    あなたはここにいくつかの非常に興味深いアイデアを入れました。 XMLの前に、私はそれを最も詳しく見ていきます。 – kastermester

    +0

    Key/Valueペアシステムに関する良いアイデア。 特に、kastermesterが潜在的にかなりの数の行をサポートしていることから、私はあなたにあまりXMLではありません。 XMLを使用すると、小さなアップデートごとにファイル全体をロード/保存する必要があります。 –

    +0

    大きなセットの場合、XMLは禁止されますが、1000/2000レコードの場合はおそらく大丈夫です。私が見つけたのは、C#はXMLを扱うのに非常に高速だということです。私のテストプログラムは、20MBのXMLファイル(10,000レコード)を読み込み、各ノードを評価し、ラップトップ上でCSVファイルに出力します。私は実際に半分の時間がCSVファイルを書くことに費やされたと推定します。私は、SQLにはXMLの "ファイル"の中でクエリを処理するための処理が組み込まれていると思う。 – Frans

    1

    非常に一般的なので非常によく似た方法でデータを保存したシステムで何かしました。

    システムは少数しか書いておらず、多くの人が読んでいて、複雑な結合によってデータを取得するとシステムがかなり遅くなりました。

    これはすべてのデータベースの慣行に反しますが、私はあなたが持っているように各テーブルのデータを非正規化し、物理的にTable_1、Table_2というデータベースにテーブルを作成しました。

    テーブルテーブルのトリガに基づいてテーブル1とテーブル2を作成して削除しましたが、TableColumnsテーブルのトリガ、TableRowsテーブルのトリガの挿入と削除、トリガの更新値TableValuesテーブルを参照してください。

    はい、予想通り、書き込みパフォーマンスは大幅に低下しましたが、これらの「非正規化」テーブルから直接読み取れるので、読み取り時のパフォーマンス(当時は非常に重要でした)が大幅に向上しました。

    したがって、実際には、実際にテーブルを作成して削除し、それに応じて列を追加および削除することができます。必要な実際のデータ型の列を作成し、必要なものを格納することができます。

    あなたが書くだけでなく、あなたのユーザーのために1つのテーブルだけを見ているだけでなく、簡単に書くことができます。

    3

    オリジナルの質問に表示するデザインは、Entity-Attribute-Valueデザインのバリエーションです。

    おそらく、ほとんどのデータベース開発者がこのデザインを「発見」し、それを使用しているものを正確に使用しようとしているということが、 CREATE TABLEALTER TABLEの不都合はありません。

    しかし、EAVには多くの欠点があります。ここには1つしかありません:特定の列を必須にするにはどうすればよいですか(NOT NULLの制約に相当)?

    リレーショナルデータベースでは、がテーブルを前もってと認識しており、それらを定義できます。 RDBMSは完全に動的な関係や、完全に可変な属性セットとの関係に適したツールではありません。 XMLには、RDF、またはCouchDBなど、さまざまなテクノロジーがあります。

    The Next-gen Databases」の回答も参照してください。

    0

    あなたは間違いなくこれを簡略化したいと思います - ユーザーがTEMPDBのようなテーブルを作成できるようにします。スキーマサフィックスを "CREATE TABLE"テーブルに単に追加するだけで、REALシステムテーブルを盛り上げないようにすることができます。フィルタリングも簡単にできます。ほとんどのデータベースでは、dba以外のユーザーがテーブルを作成することはできないため、いくつかの初期設定が必要です。このためにデータベースにスキーマを作成することもできますし、データベースがサポートしている場合は、サイズやテーブルサイズの制限に制約を置くこともできます。

    ホイールを改造しないでください。

    このようにすると、Crystal Reportsや特定のスキーマを必要としないその他のツールとの結合や結合などが自動的に行われます。

    0

    SharePointはこれをSQL Serverの上位に置いています。私は、SharePointがSQL Serverをどのように使用しているかを調べます。

    関連する問題