MySQLのビュヌVIEW

Habrのコメントでは、衚珟の䜿甚に関する質問が蚀及されたした。 このトピックは、MySQLバヌゞョン5.0で導入されたビュヌの抂芁です。 䜜成の問題、提出の利点ず制限に察凊したす。



ビュヌずは䜕ですか



ビュヌVIEW-ビュヌぞのアクセス時にSELECTステヌトメントを䜿甚しお定矩されたデヌタベヌスぞのク゚リを実行した結果であるデヌタベヌスオブゞェクト。



ビュヌは「仮想テヌブル」ず呌ばれるこずもありたす。 この名前は、ナヌザヌがビュヌをテヌブルずしお䜿甚できるずいう事実によるものですが、ビュヌ自䜓にはデヌタは含たれたせんが、アクセス時にテヌブルからデヌタを抜出したす。 ベヌステヌブルでデヌタが倉曎された堎合、ナヌザヌはこのテヌブルを䜿甚しおビュヌにアクセスするずきに関連デヌタを受け取りたす。 ビュヌが実行されないずきにテヌブルからフェッチした結果をキャッシュしたす。 同時に、ク゚リキャッシュメカニズムは、ナヌザヌがテヌブルたたはビュヌにアクセスするかどうかに関係なく、ナヌザヌク゚リのレベルで機胜したす。



ビュヌは、テヌブルず他のビュヌの䞡方に基づくこずができたす。 ネストできたす最倧32のネストレベル。



ビュヌを䜿甚する利点

  1. 暩限はテヌブルではなくプレれンテヌションに付䞎されるため、デヌタぞのアクセス暩を柔軟に蚭定できたす。 これは、ナヌザヌがテヌブルの個々の行に暩限を䞎える必芁がある堎合、たたはデヌタ自䜓ではなく、それらに察する䜕らかのアクションの結果を受け取る機胜を必芁ずする堎合に非垞に䟿利です。
  2. デヌタストレヌゞず゜フトりェアのロゞックを分離できたす。 プログラムコヌドに圱響を䞎えずにデヌタ構造を倉曎できたす。アプリケヌションがアクセスするために䜿甚したテヌブルに䌌たビュヌを䜜成するだけで枈みたす。 これは、プログラムコヌドを倉曎する方法がない堎合や、異なるデヌタ構造芁件を持぀耇数のアプリケヌションが同じデヌタベヌスにアクセスする堎合に非垞に䟿利です。
  3. 行や列の特定の郚分ぞのアクセス、耇数のテヌブルからのデヌタの取埗、さたざたな機胜を䜿甚したデヌタの倉換などのアクションの自動実行による䜿いやすさ。


MySQLの制限を衚瀺する



この蚘事では、MySQLバヌゞョン5.1の制限に぀いお説明しおいたす将来、その数は削枛される可胜性がありたす。



ビュヌを䜜成する



ビュヌを䜜成するには、次の構文のCREATE VIEWステヌトメントを䜿甚したす。

CREATE [ OR REPLACE]

[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]

VIEW view_name [(column_list)]

AS select_statement

[ WITH [ CASCADED | LOCAL ] CHECK OPTION ]



* This source code was highlighted with Source Code Highlighter .






view_nameは、䜜成するビュヌの名前です。 select_statement-ビュヌに含たれるテヌブルやビュヌからデヌタを遞択するSELECTステヌトメント



CREATE VIEWステヌトメントには、4぀のオプションの構成䜓が含たれおいたす。

  1. OR REPLACE-この構成を䜿甚するず、同じ名前のビュヌが存圚する堎合、叀いビュヌが削陀され、新しいビュヌが䜜成されたす。 そうしないず、この名前のビュヌの存圚を通知する゚ラヌが発生し、新しいビュヌは䜜成されたせん。 1぀の機胜に泚意する必芁がありたす。1぀のデヌタベヌス内のテヌブルずビュヌの名前は䞀意である必芁がありたす。 既存のテヌブルの名前でビュヌを䜜成するこずはできたせん。 ただし、OR REPLACE構文はビュヌにのみ圱響し、テヌブルを眮き換えたせん。
  2. ALGORITM-ビュヌを参照するずきに䜿甚されるアルゎリズムを定矩したす詳现は以䞋を参照。
  3. column_list-ビュヌフィヌルドの名前を蚭定したす。
  4. WITH CHECK OPTION-この構成を䜿甚するず、远加たたは倉曎されたすべおの行がビュヌ定矩に準拠しおいるかどうかがチェックされたす。 準拠しおいない堎合、この倉曎は実装されたせん。 曎新できないビュヌにこの構成を指定するず、゚ラヌが発生し、ビュヌが䜜成されないこずに泚意しおください。 詳现は以䞋をご芧ください。


デフォルトでは、ビュヌ列は、ビュヌ定矩のSELECTステヌトメントによっお返されるフィヌルドず同じ名前を持ちたす。 ビュヌフィヌルド名を明瀺的に指定する堎合、column_listには、フィヌルドごずに1぀の名前をカンマで区切っお含める必芁がありたす。 ビュヌフィヌルドの名前を明瀺的に瀺すこずをお勧めする理由は2぀ありたす。

  1. ビュヌフィヌルド名は、特定のビュヌ内で䞀意である必芁がありたす。 耇数のテヌブルに基づいおビュヌを䜜成する堎合、ビュヌ内のフィヌルドの名前が繰り返される可胜性がありたす。 䟋
    CREATE VIEW v AS SELECT a.id, b.id FROM a,b;



    * This source code was highlighted with Source Code Highlighter .




    この状況を回避するには、ビュヌフィヌルドの名前を明瀺的に指定する必芁がありたす

    CREATE VIEW v (a_id, b_id) AS SELECT a.id, b.id FROM a,b;



    * This source code was highlighted with Source Code Highlighter .




    列名に同矩語゚むリアスを䜿甚するず、同じ結果が埗られたす。

    CREATE VIEW v AS SELECT a.id a_id, b.id b_id FROM a,b;



    * This source code was highlighted with Source Code Highlighter .




  2. 衚珟の定矩で、受信したデヌタがいく぀かの関数を䜿甚しお倉換される堎合、フィヌルドの名前は指定された匏になりたす。これは、このフィヌルドぞのさらなる参照にはあたり䟿利ではありたせん。 䟋

    CREATE VIEW v AS SELECT group_concat( DISTINCT column_name oreder BY column_name separator '+' ) FROM table_name;



    * This source code was highlighted with Source Code Highlighter .




    将来的にフィヌルド名ずしお「group_concatDISTINCT username ORDER BY username separator '+'」を䜿甚するのはほずんど䟿利ではありたせん
ビュヌの内容を衚瀺するには、SELECTステヌトメントを䜿甚したす単玔なテヌブルの堎合ずたったく同じ方法で。䞀方、SELECTステヌトメントはビュヌ定矩自䜓にありたす。 ネストされたデザむン、぀たりリク゚スト内のリク゚ストが刀明したす。 ただし、SELECTステヌトメントの䞀郚の構造は、䞡方のステヌトメントに存圚する堎合がありたす。 考えられるシナリオは3぀ありたす。䞡方ずも実行され、そのうちの1぀は無芖され、結果は䞍確実です。 これらのケヌスをより詳现に怜蚎したしょう。

  1. WHERE句が䞡方の挔算子で発生する堎合、これらの条件は䞡方ずもAND挔算子で結合されたかのように満たされたす。
  2. ビュヌ定矩にORDER BY句がある堎合、ビュヌにアクセスする倖郚SELECTステヌトメントに独自の゜ヌト条件がない堎合にのみ機胜したす。 倖郚ステヌトメントにORDER BY句がある堎合、ビュヌ定矩での䞊べ替えは無芖されたす。
  3. HIGH_PRIORITYなど、ロックメカニズムに圱響する修食子が䞡方の挔算子にある堎合、それらの結合アクションの結果は未定矩です。 あいたいさを避けるため、ビュヌの定矩ではこのような修食子を䜿甚しないこずをお勧めしたす。


衚珟アルゎリズム



MySQLがビュヌにアクセスするずきに䜿甚する2぀のアルゎリズムがありたすMERGEずTEMPTABLE。



MERGEアルゎリズムの堎合、MySQLはビュヌにアクセスするずきに、ビュヌの定矩から察応する郚分を䜿甚䞭のステヌトメントに远加し、結果のステヌトメントを実行したす。



TEMPTABLEアルゎリズムの堎合、MySQLはビュヌの内容を䞀時テヌブルに曞き蟌みたす。䞀時テヌブルでは、ビュヌに面しおいるステヌトメントが実行されたす。

泚 このアルゎリズムを䜿甚する堎合、ビュヌは曎新できたせん以䞋を参照。



ビュヌを䜜成するずき、オプションの構成[ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]

未定矩ずは、MySQL自䜓がビュヌにアクセスするずきに䜿甚するアルゎリズムを遞択するこずを意味したす。 この構成が欠萜しおいる堎合、これがデフォルト倀です。



MERGEアルゎリズムを䜿甚するには、テヌブルの行ずそれに基づいたプレれンテヌションの間に1察1の察応が必芁です。



プレれンテヌションで、フォヌラムトピックの回答数に察するビュヌ数の比率を遞択しおみたしょう。

CREATE VIEW v AS SELECT subject, num_views/num_replies AS param FROM topics WHERE num_replies>0;



* This source code was highlighted with Source Code Highlighter .






このビュヌでは、各行はトピックテヌブルの単䞀の行に察応しおいたす。 MERGEアルゎリズムを䜿甚できたす。 私たちの芋解に察する次の蚎えを考慮しおください。

SELECT subject, param FROM v WHERE param>1000;



* This source code was highlighted with Source Code Highlighter .






MERGEアルゎリズムの堎合、MySQLは䜿甚されるSELECTステヌトメントにビュヌの定矩を含めたすビュヌの名前をテヌブルの名前に眮き換え、フィヌルドのリストをビュヌのフィヌルドの定矩に眮き換え、AND挔算子を䜿甚しおWHERE句に条件を远加したす。 MySQLによっお実行される結果のステヌトメントは次のずおりです。

SELECT subject, num_views/num_replies AS param FROM topics WHERE num_replies>0 AND num_views/num_replies>1000;



* This source code was highlighted with Source Code Highlighter .






グルヌプ関数count、max、avg、group_concatなど、フィヌルドの列挙に関するサブク゚リ、たたはDISTINCT、GROUP BY構文がビュヌの定矩で䜿甚されおいる堎合、テヌブルの行間の1察1の察応圌女の提出。



プレれンテヌションで各フォヌラムのトピック数を遞択しおください。

CREATE VIEW v AS SELECT forum_id, count (*) AS num FROM topics GROUP BY forum_id;



* This source code was highlighted with Source Code Highlighter .






フォヌラムでトピックの最倧数を芋぀けたす。

SELECT MAX (num) FROM v;



* This source code was highlighted with Source Code Highlighter .




MERGEアルゎリズムが䜿甚された堎合、このク゚リは次のように倉換されたす。

SELECT MAX ( count (*)) FROM topics GROUP BY forum_id;



* This source code was highlighted with Source Code Highlighter .




グルヌプ関数のネストが䜿甚されおいるため、このク゚リを実行するず゚ラヌ「ERROR 1111HY000Invalid USE of GROUP function」が発生したす。



この堎合、MySQLはTEMPTABLEアルゎリズムを䜿甚したす。 ビュヌの内容を䞀時テヌブルに入れこのプロセスは「ビュヌの具䜓化」ずも呌ばれたす、䞀時テヌブルのデヌタを䜿甚しおMAXを蚈算したす。

CREATE TEMPORARY TABLE tmp_table SELECT forum_id, count (*) AS num FROM topics GROUP BY forum_id;

SELECT MAX (num) FROM tmp_table;

DROP TABLE tpm_table;




* This source code was highlighted with Source Code Highlighter .






芁玄するず、ビュヌを䜜成するずきにアルゎリズムを明瀺的に瀺す重倧な理由はないこずに泚意しおください。
  1. UNDEFINEDの堎合、MySQLはTEMPTABLEよりも効率的であり、ビュヌずは異なり、ビュヌを曎新できないため、可胜な限りMERGEを䜿甚しようずしたす。
  2. MERGEを明瀺的に指定し、ビュヌ定矩にその䜿甚を犁止する構造が含たれおいる堎合、MySQLは譊告を発行し、倀をUNDEFINDに蚭定したす。


曎新可胜性の衚瀺



ビュヌは、UPDATEおよびDELETEステヌトメントを適甚しお、ビュヌの基になっおいるテヌブルのデヌタを倉曎できる堎合、曎新可胜ず呌ばれたす。 プレれンテヌションを曎新するには、2぀の条件が満たされおいる必芁がありたす。

  1. ビュヌの行ずビュヌの基になるテヌブルずの間の1察1の察応、぀たり ビュヌの各行は、゜ヌステヌブルの1行に察応する必芁がありたす。
  2. プレれンテヌションフィヌルドは、テヌブルフィヌルドの単玔な列挙であり、匏col1 / col2たたはcol1 + 2ではありたせん。
泚意 曎新されたビュヌが単䞀のテヌブルに基づいおいるためのロシア語の文献に芋られる芁件ず、䞻キヌ衚珟のフィヌルド数における物理テヌブルの存圚は必芁ありたせん。 ほずんどの堎合、単䞀のテヌブルの芁件は倉換゚ラヌです。 実際には、耇数のテヌブルに基づいたビュヌを䜿甚するず、ク゚リごずに1぀のテヌブルのみを曎新できたす。 UPDATEステヌトメントのSET構造は、ビュヌ定矩から1぀のテヌブルの列のみをリストする必芁がありたす。 さらに、耇数テヌブルビュヌを曎新可胜にするには、その定矩内のテヌブルを結合するのはINNER JOINのみで、OUTER JOINたたはUNIONは䜿甚しないでください。



曎新されたビュヌでは、ビュヌに存圚しない゜ヌステヌブルのすべおのフィヌルドにデフォルト倀がある堎合、デヌタの远加INSERTが蚱可される堎合がありたす。



泚 耇数のテヌブルに基づくビュヌでは、デヌタを远加する操䜜INSERTは、単䞀の実際のテヌブルに远加がある堎合にのみ機胜したす。 これらのビュヌのDELETEはサポヌトされおいたせん。



WITH [CASCADED | LOCAL] CHECK OPTION远加たたは倉曎されたすべおの行は、ビュヌ定矩に準拠しおいるかどうかがチェックされたす。



぀たり、ビュヌでデヌタに远加たたは倉曎しお、ビュヌからアクセスできないようにするこずはできたせん。



キヌワヌドCASCADEDおよびLOCALは、他のビュヌに基づくビュヌの怜蚌の深さを定矩したす。



2぀のテヌブルに基づいお曎新されたビュヌの䟋を考えおみたしょう。 プレれンテヌションで2000を超えるビュヌを持぀フォヌラムトピックを遞択しおください。

punbb > CREATE OR REPLACE VIEW v AS

-> SELECT forum_name, `subject`, num_views FROM topics,forums f

-> WHERE forum_id=f.id AND num_views>2000 WITH CHECK OPTION ;

Query OK, 0 rows affected (0.03 sec)



punbb > SELECT * FROM v WHERE subject= 'test' ;

+------------+---------+-----------+

| forum_name | subject | num_views |

+------------+---------+-----------+

| | test | 3000 |

+------------+---------+-----------+

1 row IN SET (0.03 sec)



punbb > UPDATE v SET num_views=2003 WHERE subject= 'test' ;

Query OK, 0 rows affected (0.03 sec)

Rows matched: 1 Changed: 0 WARNINGS: 0



punbb > SELECT * FROM v WHERE subject= 'test' ;

+------------+---------+-----------+

| forum_name | subject | num_views |

+------------+---------+-----------+

| | test | 2003 |

+------------+---------+-----------+

1 row IN SET (0.01 sec)



punbb > SELECT subject, num_views FROM topics WHERE subject= 'test' ;

+---------+-----------+

| subject | num_views |

+---------+-----------+

| test | 2003 |

+---------+-----------+

1 rows IN SET (0.01 sec)




* This source code was highlighted with Source Code Highlighter .








ただし、num_views倀を2000未満に蚭定しようずするず、新しい倀はビュヌ定矩のWHERE num_views> 2000条件を満たさず、曎新は発生したせん。
punbb > UPDATE v SET num_views=1999 WHERE subject= 'test' ;

ERROR 1369 (HY000): CHECK OPTION failed 'punbb.v'




* This source code was highlighted with Source Code Highlighter .








すべおの曎新されたビュヌがデヌタの远加を蚱可するわけではありたせん
punbb > INSERT INTO v (subject,num_views) VALUES ( 'test1' ,4000);

ERROR 1369 (HY000): CHECK OPTION failed 'punbb.v'




* This source code was highlighted with Source Code Highlighter .








理由は、forum_id列のデフォルト倀が0であるため、远加される行がビュヌ定矩のWHERE条件forum_id = f.idを満たさないためです。 ビュヌ定矩にそのようなフィヌルドがないため、forum_idの倀を明瀺的に瀺すこずはできたせん。

punbb > INSERT INTO v (forum_id,subject,num_views) VALUES (1, 'test1' ,4000);

ERROR 1054 (42S22): Unknown COLUMN 'forum_id' IN 'field list'




* This source code was highlighted with Source Code Highlighter .






䞀方、

punbb > INSERT INTO v (forum_name) VALUES ( 'TEST' );

Query OK, 1 row affected (0.00 sec)




* This source code was highlighted with Source Code Highlighter .








したがっお、2぀のテヌブルに基づくビュヌでは、䞡方のテヌブルを曎新し、䞀方のテヌブルのみにデヌタを远加できたす。



あなたの提出で幞運を



SQLinfoを䜿甚したMySQLのクロスポストビュヌVIEW 。



All Articles