2

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

これまでの私の考えは、2つのテーブルを使用してデータベースでこれを表すことです。1つのテーブルがテーブルを表し、1つのテーブルがテーブルの列を表し、1つのテーブルがテーブルの各行を表し、最後に1つが値を表します。 。(PSEUDO 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テーブルをクエリすることでした-フィルタリングのために、列が基準に一致しなかった行をフィルターで除外し、並べ替えのために、列の内容に基づいてRowIdを並べ替えました(指定された並べ替えで指定されたとおり)。希望する順序で行IDのリストが作成されます。これ以降は、必要なものを選択するだけで済みます。

これはすべて正常に機能しますが、これからは少し行き詰まります。どういうわけか、さまざまなデータ型を表現できるようにしたいと思います(これは私の主な問題です)。また、後で結合を行う方法を検討します。

このすべてを考えている間、私はこれを行うためのより良い方法があるかどうか疑問に思い始めます。もちろん、ここでのパフォーマンスが要因であることに注意してください。ただし、数十万行、おそらく仮想テーブルあたり約1000行の仮想テーブルをサポートする予定はありません。もちろん、システム全体で多くのこれらは。

これを実現するために、C#でオンザフライで作成されたクエリを使用して、データベースにテーブルを実際に作成できます。同様に、SQLクエリのみを使用してクエリを実行できます。ただし、ユーザーがデータベースに対してクエリを「構築」できるようにすることは、これまで大ファンではありませんでした。このように-そしてそれは多くのバグが現れる道をたどるだろうように私には思えます-そして最悪の場合のシナリオはユーザーが何らかの方法でデータベースを殺すことを許してしまうでしょう。

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

ですから、私が本当に望んでいるのは、これを行う方法のアイデア、パフォーマンスを調整する方法のアイデア、テーブル内の個別のデータ型を処理する方法のアイデアです(もちろん、タイプをテーブル列に格納しますが、実際に値を格納して、フィルターや並べ替えなどを実行できるようにしますか?-tablevaluesテーブルに「TextValue」や「MoneyValue」などの列を追加するだけではありません)。そして最後になりましたが、ここでいくつかの良い議論ができれば幸いです。少なくとも、これはやや興味深いトピックだと思います。

4

9 に答える 9

9

どういうわけか、誰もがどこかでそのアイデアに出くわします。

それは正しいようです、それはうまくいくはずです。

そうなるでしょう。ある種。

TheDailyWTFに関するコメントには意味があります。DBMSの上にDBMSを再実装することは、実際には良い考えではありません。そのようにメタに行くことはあなたに与えるだろう

  • 性能不足のシステム
  • メンテナンスの悪夢

そのような柔軟性が本当に必要な場合(そうですか?)、メタデータをいくつかのテーブルに格納し、データベース内の実際のテーブルのスキーマを生成できるレイヤーの実装に時間を費やす方がはるかに良いでしょう。

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

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

そして、私は他にもあると確信しています。

この種の設計の利点は、データベースが最終的には実際に意味をなし、その強みとしてRDBMSを使用することです。また、この種の構成は、テーブルが作成された後は常に行われるべきではないため、ユーザーは必要に応じてデータベースを微調整できます(主にインデックス作成の観点から)。

あなたが提案する種類のシステムに対する唯一の正解は、そうではないことだと私は本当に強く感じています。

于 2009-05-28T16:48:23.637 に答える
6

これは興味深いアイデアですが、SQLをこのように使用することは、時間の経過とともに非常に苦痛になるでしょう。
正しく理解できれば、ユーザーがデータ構造を定義して、それらの構造にデータを保存できるようにする必要があります。また、クエリを実行できるようにする必要があります。これについては、他にもいくつかの方法があると思います。

  • XMLの使用はどうですか?各ユーザーが「テーブル」ごとにXMLファイルを保存し、そのスキーマを維持できるようにします。各「行」は、子要素を持つXML要素になります。オプションで、XMLをSQLに固定するか、他の方法で保存することができます。これは大規模なデータセットではうまく機能しませんが、何千ものレコードの場合、驚くほど高速です。C#で20 MB以上のXMLファイルを使用していくつかのテストを行い、それらを作成して読み取り、1秒未満で解析することができました。LINQ to XMLを使用すると、かなり洗練されたクエリと結合を構築することもできます。大規模なエンタープライズシステムにはXMLを使用しませんが、大量のメモリと高速プロセッサを備えた最新のマシンでXMLがどこまで使用できるかに驚かれることでしょう。また、XMLは非常に柔軟です。
  • 代わりに、オブジェクト指向データベース(Matisseなど)を使用できますか?私自身はこれらの経験はありませんが、XMLアプローチのようなことは非常に簡単に実行できますが、パフォーマンスは向上すると思います。
  • Amazon Simple DB:私が正しく覚えていれば、これは基本的に、使用できる名前/値ペアベースのデータベースです。アプリケーションは、すべての配管を処理する必要をなくすために、代わりにバックグラウンドでそれを使用できますか?SQL Serverの料金を支払う必要がある場合は、Amazon DBの方が安価で、大規模に拡張できる可能性がありますが、リレーショナルクエリなどの機能はありません。
于 2009-05-28T16:48:53.480 に答える
3

元の質問で示したデザインは、Entity-Attribute-Valueデザインのバリエーションです。

一部の人々が表現している焦りは、事実上すべてのデータベース開発者がこの設計を「発見」し、それを使用している目的に正確に使用しようとしているという事実によるものと思われます。とを使用CREATE TABLEALTER TABLEます。

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

リレーショナルデータベースは、テーブルを事前に知っていることを前提としており、テーブルを定義できます。RDBMSは、完全に動的な関係または完全に可変の属性セットを持つ関係に適したツールではありません。XML、 RDFCouchDBなど、他にも多くのテクノロジーがあります。

「次世代データベース」に対する私の回答も参照してください。

于 2009-05-28T17:31:41.647 に答える
2

多数の反対票を投じるリスクがあるので、MSAccessをインストールしてもらいませんか。

于 2009-05-28T16:27:31.683 に答える
1

Outlook用のMicrosoftのBusinessContactManagerアドインで、このようなアプローチに遭遇しました。フィールドタイプを処理する方法は、各フィールドのタイプを定義するテーブルを用意し、実際のフィールド値をVarbinary列のみを含むテーブルに格納することです。varbinaryとの間の変換は、フィールドタイプテーブルによって制御されます。

于 2009-05-28T16:40:19.457 に答える
1

なぜすべての憎しみがあり、誰も実際にあなたの質問に答えようとしていないのかわかりません。最終的には「Googleドキュメントをどのように実装しますか」という質問であっても、それでも公正な質問です。

あなたが本当にこれをやりたいかどうかを考えたと仮定すると(私はすべての憎しみが約であると私は仮定しています)、少なくともより良いアイデアがあります:

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

次に、特定のTABLEIDの名前、使用されているフィールド、ユーザー向けの名前などを記録するメタデータをどこかに保存します。結合はデータテーブルでの自己結合であるため、簡単にサポートできます。上記のメタデータをデータベースに保存するか、他の場所に保存するかはあなた次第です。

このアプローチは完全にうまく機能します(多くの成功した.comサイトがこの種のスキーマを使用していることを証明できます。私が関わっていた、または関わっていた人々を知っていました)が、最適なパフォーマンスを得るには、VARCHARよりもCHARを使用することをお勧めします、タプルをページにうまく収まるように配置するなど。

これはdsteeleの答えとかなり(非常に)似ていると思います

于 2009-05-28T16:47:42.220 に答える
1

非常に一般的な、したがって非常に類似した方法でデータを格納したシステムに対して、私は何かをしました。

システムは書き込みが少なく、読み取りが多く、データを取り出すための複雑な結合により、システムが非常に遅くなりました。

これはすべてのデータベースの慣例に反することがわかりましたが、各「テーブル」のデータを非正規化し、Table_1、Table_2という名前のテーブルをデータベースに物理的に作成しました。

Tablesテーブルのトリガーに基づいてTable_1とTable_2を作成および削除し、TableColumnsテーブルのトリガーを使用してこれらのテーブルに列を追加および削除し、TableRowsテーブルのトリガーを使用して行を挿入および削除し、TableValuesテーブルのトリガーを使用して値を更新しました。

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

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

ユーザーの単一のテーブルのみを表示しているだけでなく、作成するクエリがはるかに簡単になる可能性があります。

于 2009-05-28T16:50:23.197 に答える
0

あなたは間違いなくこれを単純化したいと思います-おそらくTEMPDBでユーザーがテーブルを作成できるようにします。「CREATETABLE」dテーブルの前にスキーマ接尾辞を付けるだけで、REALシステムテーブルを混乱させることを回避できる場合があります。それらも簡単にフィルタリングできます。問題は、ほとんどのデータベースが非dbaによるテーブルの作成を許可しないため、事前のセットアップが必要になることです。このためにデータベースにスキーマを作成し、データベースでサポートされている場合は、サイズとテーブルサイズの制限に制約を課すこともできます。

車輪の再発明をしないでください。

このようにすると、結合、結合などが自動的に取得され、CrystalReportsや特定のスキーマをgrokkinする必要のないその他のツールとのインターフェイスが得られます。

于 2009-05-28T17:41:41.457 に答える
0

SharePointは、SQLServer上でこれ以上のことを行います。SharePointがSQLServerをどのように使用しているかを調査します。

于 2009-05-28T18:00:48.907 に答える