44

ビューを作成するとき、基本的には、結合するテーブルのいずれかのデータが変更されたときに自動的に処理される新しいテーブルを作成しています。あれは正しいですか?

また、ビューでサブクエリを使用できないのはなぜですか?

4

3 に答える 3

58

ビューはテーブルのように機能しますが、テーブルではありません。それは決して存在しません。ビュー名を参照するときに実行されるのは、準備された SQL ステートメントだけです。いいえ:

CREATE VIEW foo AS
  SELECT * FROM bar

SELECT * FROM foo

...実行することと同等です:

SELECT x.* 
  FROM (SELECT * FROM bar) x

MySQLDump には、ビューに挿入される行が含まれることはありません...

また、ビューでサブクエリを使用できないのはなぜですか????

悲しいことに、それは (疑わしいとはいえ) 設計によるものです。MySQL ビューには多数の制限があり、文書化されています: http://dev.mysql.com/doc/refman/5.0/en/create-view.html

したがって、それが単なる架空のテーブル/準備されたステートメントである場合、それは理論的には通常のテーブル/クエリと同じ (またはそれ以下) のパフォーマンスを持っていることを意味しますか?


いいえ
。テーブルにはインデックスを関連付けることができます。これにより、データの取得が高速化されます (挿入/更新に多少のコストがかかります)。一部のデータベースは、インデックスを適用できるビューである「マテリアライズド」ビューをサポートしています。これは、限られたビュー機能 (v5 IIRC でのみ開始され、ゲームの非常に遅い段階) を考えると、 MySQLがサポートしていないことは驚くべきことではありません。 )。

ビューは派生テーブルであるため、ビューのパフォーマンスは、それが構築されているクエリと同じくらい良くなります。そのクエリがうまくいかない場合、パフォーマンスの問題は雪だるま式になります...とは言っても、ビューをクエリするとき-WHERE句のビュー列参照が関数でラップされていない場合(IE: WHERE v.column LIKE ..., not WHERE LOWER(t.column) LIKE ... )、オプティマイザは基準をプッシュする可能性があります(述語と呼ばれます) を元のクエリに追加して、高速化します。

于 2010-05-20T22:22:26.293 に答える
2

私も同じ問題に遭遇しました(驚いたことに、私の検索ではOracleとMSがそれをサポートしていることが示されているようです)。

最終ビュー用に2つの追加ビューを作成することで、この制限を回避します(少なくとも今のところ、使用できないことが証明されるまで)。

例:

CREATE VIEW Foo1 AS
    SELECT * FROM t ORDER BY ID, InsertDate DESC

CREATE VIEW Foo2 AS
    SELECT * FROM Foo1 GROUP BY ID

CREATE VIEW Foo AS
    SELECT * FROM Foo2 ORDER BY ID

上記の例には、基本的に、すべてのリビジョンを含む一時テーブルであるテーブル't'があります。私の「Foo」(ビュー)は基本的に、各レコードの最新のリビジョンのみの単純なビューです。今のところ問題なく動作しているようです!

アップデート:

これがMySQL5.1の別のバグであるかどうかはわかりませんが、上記の例は実際には機能しません。「Foo1」は期待どおりに機能しますが、「Foo2」はグループ化する前の順序を無視しているように見えるため、最終結果は意図したものではありません。「ASC」の「DESC」を変更しても同じ結果が得られます(驚くべきことに)。

また、 17.5.1を読んだ場合。構文セクションを表示すると、次のように明確に示されます。

「ビューは、さまざまな種類のSELECTステートメントから作成できます。ベーステーブルまたは他のビューを参照できます。結合、UNION、およびサブクエリを使用できます。」

データベースを5.6に更新して、再試行します。

于 2011-08-11T05:54:47.290 に答える
2

違いは次のとおりです。

ビューの場合、サブクエリは where - 部分にのみ使用でき、 from - 部分には使用できないため、

CREATE VIEW v AS SELECT * FROM foo WHERE id IN (SELECT id FROM bar) 

動作しますが、同時に読み取り専用ビューを取得します...単一のテーブルの単純なビューでは、ビューを基になるテーブルに「介して」更新できます

于 2013-08-08T08:46:35.220 に答える