Lorsque je crée une vue, je crée essentiellement une nouvelle table qui sera automatiquement traitée lorsque les données de l'une des tables qu'elle rejoint changeront; Est-ce exact?
Pourquoi ne puis-je pas utiliser de sous-requêtes à mon avis?
Une vue fonctionne comme une table, mais ce n'est pas une table. Cela n'existe jamais; il s'agit uniquement d'une instruction SQL préparée qui est exécutée lorsque vous référencez le nom de la vue. C'EST À DIRE:
CREATE VIEW foo AS
SELECT * FROM bar
SELECT * FROM foo
... équivaut à courir:
SELECT x.*
FROM (SELECT * FROM bar) x
Un MySQLDump ne contiendra jamais de lignes à insérer dans une vue ...
Aussi pourquoi ne puis-je pas utiliser de sous-requêtes à mon avis ????
Malheureusement, c'est par conception (quoique discutable). Il existe de nombreuses limitations pour les vues MySQL, qui sont documentées: http://dev.mysql.com/doc/refman/5.0/en/create-view.html
Non.
Une table peut avoir des index associés, ce qui peut accélérer la récupération des données (à un certain coût pour l'insertion/la mise à jour). Certaines bases de données prennent en charge les vues "matérialisées", qui sont des vues auxquelles des index peuvent être appliqués - ce qui ne devrait pas être une surprise si MySQL ne prend pas en charge étant donné la fonctionnalité de vue limitée (qui n'a commencé que dans la v5 IIRC, très tard dans le jeu).
Dans la mesure où une vue est une table dérivée, les performances de la vue sont uniquement aussi bonnes que la requête sur laquelle elle est construite. Si cette requête est nulle, le problème de performances sera juste Snowball ... Cela dit, lors de l'interrogation d'une vue - si une référence de colonne de vue dans la clause WHERE n'est pas encapsulée dans une fonction (IE: WHERE v.column LIKE ...
, pas WHERE LOWER(t.column) LIKE ...
), l'optimiseur peut pousser les critères (appelés prédicats) sur la requête d'origine - ce qui les rend plus rapides.
J'ai également rencontré le même problème (à ma grande surprise, car ma recherche semble indiquer qu'Oracle et MS le prennent en charge).
Je contourne cette limitation (du moins pour l'instant, jusqu'à ce qu'elle soit prouvée non utilisable) en créant deux vues supplémentaires pour ma vue finale.
Exemple:
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
L'exemple ci-dessus a essentiellement une table "t" qui est une table temporelle contenant toutes les révisions. Mon 'Foo' (vue) est essentiellement une vue simple de mes révisions les plus récentes de chaque enregistrement. Semble bien fonctionner pour l'instant!
Mettre à jour:
Je ne sais pas s'il s'agit d'un autre bogue dans MySQL 5.1, mais l'exemple ci-dessus ne fonctionne pas en fait! Le 'Foo1' fonctionne comme prévu, mais le 'Foo2' semble ignorer l'ordre avant le regroupement, donc mon résultat final n'est pas ce qui est prévu. J'obtiens même le même résultat si je change le 'DESC' pour 'ASC' (étonnamment).
De plus, si vous lisez le 17.5.1. Afficher la syntaxe section, il indique clairement:
"Une vue peut être créée à partir de nombreux types d'instructions SELECT. Elle peut faire référence à des tables de base ou à d'autres vues. Elle peut utiliser des jointures, UNION et des sous-requêtes."
Je vais mettre à jour ma base de données vers 5.6 et réessayer!
La différence est:
pour la vue, vous ne pouvez avoir des sous-requêtes que dans la partie où - pas dans la partie de - donc un
CREATE VIEW v AS SELECT * FROM foo WHERE id IN (SELECT id FROM bar)
fonctionnerait - mais en même temps vous obtenez une vue en lecture seule ... Une vue simple sur une seule table permettrait de mettre à jour "à travers" la vue vers la table sous-jacente