MySQL Identifier Otázka




Od například otázky MySQL průvodce certifikace je ... 


**otázka** 



```
Bude následující příkaz SQL podaří, nebo mít za následek chybu? Předpokládejme, že tabulka bude vytvořena již neexistuje.

CREATE TABLE MD5 (id INT);
```

**Odpovědět**



```
Výsledky výkazu vygeneruje chybu, pokud je aktivován režim IGNORE\_SPACE SQL. V tomto případě jsou všechny funkce názvy stávají vyhrazená slova a příkaz vrátí chybu, protože MD5 je název funkce.

Není-li povolen režim IGNORE\_SPACE SQL, prohlášení následuje:

MySQL> CREATE TABLE MD5 (id INT);
Dotaz OK, 0 řádků postižených


Všimněte si, že režim IGNORE\_SPACE SQL je součástí režimu ANSI SQL. 
```

Proč se mluví o prostor? Každý, kdo má nějaký nápad? Jaká bude správná odpověď? To se nezdaří, protože funkce je vyhrazené slovo? Bude to podaří, když citoval, např. s backtick ... jo?
[`IGNORE_SPACE`](http://dev.mysql.com/doc/refman/5.1/en/server-sql-mode.html#sqlmode_ignore_space)Režim umožňuje mezery mezi názvy funkcí a následující závorkách. Pokud je to povoleno, všechny názvy funkcí se stal vyhrazená slova, protože to stane se nemožné pro MySQL, zda voláte funkce nebo deklarovat (s použitím) identifikátor.


Proto, pokud je to povoleno, vaše `CREATE TABLE`selže a následující:



```
SELECT MD5 (some_column) FROM some_table

```

bude pracovat. Pokud `IGNORE_SPACE`je vypnuta, opak stane ( `CREATE TABLE`bude fungovat a především `SELECT`nebude, protože tam je mezera mezi názvu funkce a závorce).
<p> <a href="https://dev.mysql.com/doc/refman/8.0/en/integer-types.html"><code>int</code> a <code>smallint</code> mají různé velikosti a následně rozsahy.</a> <code>(5)</code> je <code>smallint(5)</code> nebo <code>int(5)</code> se nazývá <a href="https://dev.mysql.com/doc/refman/8.0/en/numeric-type-attributes.html">"atribut číselného typu"</a> a představuje "šířku zobrazení" pole,</p><blockquote> <p>mysql podporuje rozšíření pro volitelné určení šířky zobrazení celočíselných datových typů v závorkách následujících za základním klíčovým slovem pro daný typ. například <code>int(4)</code> určuje <code>int</code> se šířkou zobrazení čtyř číslic. tuto volitelnou šířku zobrazení mohou aplikace použít k zobrazení celočíselných hodnot, jejichž šířka je menší než šířka specifikovaná pro sloupec, přičemž je doleva vyplní mezerami. (to znamená, že tato šířka je přítomna v metadatech vrácených se sadami výsledků. zda se používá nebo ne, závisí na aplikaci.)</p> <p>při použití ve spojení s volitelným (nestandardním) atributem <code>zerofill</code> je výchozí výplň mezer nahrazena nulami. například pro sloupec deklarovaný jako <code>int(4) zerofill</code> je hodnota <code>5</code> načtena jako <code>0005</code>.</p> </blockquote><p>toto je mysql "rozšíření" a zerofill je "rozšíření" na rozšíření.</p><p>pro rozumný způsob ovládání zobrazení číselného typu nepoužívejte atributy numeric type a místo toho použijte</p><ul> <li> <a href="https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function\_format"><code>format</code></a> </li> <li> <a href="https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function\_lpad"><code>lpad</code></a> </li> <li> <a href="https://dev.mysql.com/doc/refman/8.0/en/string-functions.html#function\_lpad"><code>rpad</code></a> </li> </ul> <p>protože ostatní odpovědi již naznačují, sql server může nebo nemusí explicitně zajistit, že řádky jsou seřazeny v pořadí seskupených indexů před <code>insert</code>.</p><p>to závisí na tom, zda má klastrovaný indexový operátor v plánu sadu vlastností <code>dmlrequestsort</code> (což zase závisí na odhadovaném počtu řádků, které jsou vloženy).</p><p>pokud zjistíte, že sql server to z jakéhokoli důvodu podceňuje, můžete mít prospěch z přidání explicitního <code>order by</code> k dotazu <code>select</code> k minimalizaci rozdělení stránek a následné fragmentaci z operace <code>insert</code></p><p><strong> příklad: </strong></p><pre><code>use tempdb; go create table t(n int primary key,filler char(2000)) create table t2(n int primary key,filler char(2000)) go declare @t table (u uniqueidentifier primary key default newid(),n int) insert into @t(n) select number from master..spt\_values where type = 'p' and number between 0 and 499 /*estimated row count wrong as inserting from table variable*/ insert into t(n) select t1.n*1000 + t2.n from @t t1, @t t2 /*same operation using explicit sort*/ insert into t2(n) select t1.n*1000 + t2.n from @t t1, @t t2 order by t1.n*1000 + t2.n select avg\_fragmentation\_in\_percent, fragment\_count, page\_count, avg\_page\_space\_used\_in\_percent, record\_count from sys.dm\_db\_index\_physical\_stats(2, object\_id('t'), null, null, 'detailed') ; select avg\_fragmentation\_in\_percent, fragment\_count, page\_count, avg\_page\_space\_used\_in\_percent, record\_count from sys.dm\_db\_index\_physical\_stats(2, object\_id('t2'), null, null, 'detailed') ; </code></pre><p>ukazuje, že <code>t</code> je masivně roztříštěný</p><pre><code>avg\_fragmentation\_in\_percent fragment\_count page\_count avg\_page\_space\_used\_in\_percent record\_count      99.3116118225536 92535 92535 67.1668272794663 250000 99.5 200 200 74.2868173956017 92535 0 1 1 32.0978502594514 200 </code></pre><p>ale pro <code>t2</code> fragmentace je minimální</p><pre><code>avg\_fragmentation\_in\_percent fragment\_count page\_count avg\_page\_space\_used\_in\_percent record\_count      0.376 262 62500 99.456387447492 250000 2.1551724137931 232 232 43.2438349394613 62500 0 1 1 37.2374598468001 232 </code></pre><p>naopak někdy budete chtít donutit sql server, aby podceňoval počet řádků, když víte, že data jsou již předem roztříděna a chcete zabránit zbytečnému třídění. jedním z pozoruhodných příkladů je vložení velkého počtu řádků do tabulky pomocí seskupeného indexového klíče <code>newsequentialid</code>. <a href="https://connect.microsoft.com/sqlserver/feedback/details/668540/unnecessary-sort-operation-for-insert-into-clustered-index-with-newsequentialid-key">ve verzích sql serveru před denali sql server přidává zbytečnou a potenciálně nákladnou operaci řazení</a> . tomu lze zabránit</p><pre><code>declare @var int =2147483647 insert into foo select top (@var) * from bar </code></pre><p>sql server poté odhadne, že bude vloženo 100 řádků bez ohledu na velikost <code>bar</code>, která je pod prahem, při kterém je do plánu přidáno řazení. jak je však uvedeno v poznámkách níže, znamená to, že vložka bohužel nebude moci využít výhody minimálního protokolování.</p> <blockquote> <p>existuje v sql konstrukt, který by mi umožnil dělat něco jako následující:</p> </blockquote><p>ano, existuje téměř přesně tak, jak jste to napsali. stačí do závorek vložit <code>col1, col2</code>:</p><pre><code>-- works in postgresql, oracle, mysql, db2, hsqldb select whatever from t  you missed the from where (col1, col2)  parentheses here in ((val1a, val2a), (val1b, val2b), ...) ; </code></pre><p>pokud to zkusíte v dbms, možná zjistíte, že to nefunguje. protože ne všechny dbms implementovaly všechny funkce (vyvíjejícího se) standardu sql. funguje to v nejnovějších verzích oracle, mysql, postgres, db2 a hsqldb (nebylo to v mysql dobře optimalizováno a nepoužívaly indexy, proto by se tam nemělo vyhýbat, pokud to neřeší v 5.7).</p><p>viz mysql dokumentace o <a href="https://dev.mysql.com/doc/refman/5.7/en/comparison-operators.html#function\_in"><code>in</code> operator</a> a postgres dokumentace o <a href="https://www.postgresql.org/docs/current/static/sql-expressions.html#sql-syntax-row-constructors">row konstruktory</a> . dvě * (nebo více) hodnot v závorkách se nazývají konstruktory řádků <strong> </strong>.</p><p>další způsoby, které vyjadřují stejnou myšlenku:</p><pre><code>-- works in postgresql, db2 select whatever from t where (col1, col2) in ( values (val1a, val2a), (val1b, val2b), ...) ; select t.whatever from t join ( values (val1a, val2a), (val1b, val2b), ...) as x (col1, col2) on (x.col1, x.col2) = (t.col1, t.col2) ; </code></pre><p>oba pracují v postgresu a db2 (afaik). poslední může být také upraven tak, aby fungoval na serveru sql server:</p><pre><code>-- works in postgresql, db2, sql server select t.whatever from t join ( values (val1a, val2a), (val1b, val2b), ...) as x (col1, col2) on x.col1 = t.col1 and x.col2 = t.col2 ; </code></pre><p>může být také upraven tak, aby fungoval všude, nejprve uložením hodnot do (dočasné nebo trvalé) tabulky:</p><pre><code>-- works everywhere create table values\_x ( col1 ..., col2 ...) ; -- use appropriate for the dbms syntax here insert into values\_x (col1, col2) values (val1a, val2a), (val1b, val2b), ... ; select t.whatever from t join values\_x x on x.col1 = t.col1 and x.col2 = t.col2 ; drop table values\_x ; </code></pre><p>a vždy existuje dlouhá cesta nebo převod <code>in</code> na dlouhý výraz s <code>or</code>, který by měl fungovat všude:</p><pre><code>-- works in all sql dbms select whatever from t where col1 = val1a and col2 = val2a or col1 = val1b and col2 = val2b  ; </code></pre><p>*: ve skutečnosti to může být jen jedna hodnota, s <code>row(v)</code>, viz postgres docs.</p> <p>pravděpodobně se dostáváte do radostí mysql myisam engine ...</p><p>v rámci mysql (nebo phpmyadmin) použijte příkazy repair table xyz znovu, opakovaně, na každé z vašich tabulek (nebo spíše tabulek souvisejících s vašimi podmínkami, protože to jsou ty, které znějí zkaženě), aby se zjistilo, zda to nic nevyřeší.</p><p>pokud selžou, existuje několik zdokumentovaných řešení:</p><p> <a href="http://www.google.com/search?q=recover+a+corrupt+mysql+database">http://www.google.com/search?q=recover+a+corrupt+mysql+database</a> </p><p>jakmile jsou věci obnoveny, spusťte příkazy optimalizovat tabulku xyz na každé tabulce a poté změňte motor databáze a každou tabulku, aby byla použita innodb. innodb poněkud neuspořádá katalog (zejména pokud upustíte databázi nebo velké tabulky), ale - pokud je kompatibilní s acid - je to o dost méně náchylné k chybám než myisam.</p> <p>musíte použít tuto kombinaci kláves:</p><blockquote> <p><kbd>ctrl</kbd> + <kbd>shift</kbd> + <kbd>r</kbd></p> </blockquote><p>případně použijte položku nabídky:</p><blockquote> <p>úpravy&gt; intellisense&gt; aktualizovat místní mezipaměť</p> </blockquote><p>tento článek může být také užitečný (pro budoucí čtenáře, kteří mají komplikovanější problémy s intellisense):</p><ul> <li> <a href="http://www.mssqltips.com/sqlservertip/2591/troubleshooting-intellisense-in-sql-server-management-studio-2012/">odstraňování problémů s intellisense v sql server management studio</a> </li> </ul> <p>nejprve byste si měli být naprosto jistí, že musíte iterovat přes jednotlivé řádky - operace založené na sadě budou fungovat rychleji v každém případě, na který si pomyslím, a obvykle použiji jednodušší kód.</p><p>v závislosti na vašich datech může být možné opakovat smyčky pouze pomocí vybraných příkazů, jak je uvedeno níže:</p><pre><code>declare @id int while (select count(*) from atable where processed = 0) &gt; 0 begin select top 1 @id = id from atable where processed = 0 --do some processing here update atable set processed = 1 where id = @id end </code></pre><p>další alternativou je použití dočasné tabulky:</p><pre><code>select * into #temp from atable declare @id int while (select count(*) from #temp) &gt; 0 begin select top 1 @id = id from #temp --do some processing here delete #temp where id = @id end </code></pre><p>možnost, kterou byste si měli vybrat, opravdu závisí na struktuře a objemu vašich dat.</p><p><strong> poznámka: </strong> pokud používáte sql server, měli byste být lépe obsluhováni pomocí:</p><pre><code>while exists(select * from #temp) </code></pre><p>pomocí <code>count</code> se bude muset dotknout každého jednotlivého řádku v tabulce, <code>exists</code> se musí dotknout pouze prvního (viz <a href="https://stackoverflow.com/a/65294/963542">josefova odpověď</a> níže).</p> <p>funkci <a href="https://www.postgresql.org/docs/current/static/functions-info.html#functions-info-catalog-table"><code>pg\_get\_constraintdef(constraint\_oid)</code></a> můžete použít v dotazu, jako je následující:</p><pre><code>select conrelid::regclass as table\_from , conname , pg\_get\_constraintdef(oid) from pg\_constraint where contype in ('f', 'p ') and connamespace = 'public'::regnamespace -- your schema here order by conrelid::regclass::text, contype desc; </code></pre><p>výsledek:</p><pre><code> table\_from | conname | pg\_get\_constraintdef ++ tbl | tbl\_pkey | primary key (tbl\_id) tbl | tbl\_col\_fk | foreign key (col) references tbl2(col) on update cascade ... </code></pre><p>vrací všechny primární a cizí klíče pro všechny tabulky v daném schématu, seřazené podle tablename, pks nejprve.</p><p> <a href="https://www.postgresql.org/docs/current/static/catalog-pg-constraint.html">manuál o <strong> <code>pg\_constraint</code> </strong>.</a> </p><p> <a href="https://www.postgresql.org/docs/current/datatype-oid.html">manuál o <strong> typech identifikátorů objektů </strong></a> (<code>regclass</code>, <code>regnamespace</code>, ...) .</p> <p><strong> aktualizace leden 2017 - sql server 2016+/azure sql database </strong></p><p>sql server 2016 a aktuální verze azure sql database má nyní následující syntaxi pro funkce, procedury, tabulky, databáze atd. ( <a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2015/11/03/drop-if-exists-new-thing-in-sql-server-2016/"><code>drop if exists</code></a> ):</p><pre><code>drop function if exists dbo.fn\_myfunc; </code></pre><p>a sql server 2016 service pack 1 přidává ještě lepší funkčnost pro moduly (funkce, procedury, spouštěče, zobrazení), což znamená, že nedochází ke ztrátě oprávnění nebo závislostí ( <a href="https://blogs.msdn.microsoft.com/sqlserverstorageengine/2016/11/17/create-or-alter-another-great-language-enhancement-in-sql-server-2016-sp1/"><code>create or alter</code></a> ):</p><pre><code>create or alter function dbo.fn\_myfunc ... </code></pre><p>obě tato vylepšení syntaxe mohou vést k mnohem jednodušším skriptům používaným pro řízení zdroje, nasazení atd.</p><p>ale pokud používáte ...</p><hr><p><strong> starší verze </strong></p><p>při skriptu z management studio je třeba udělat to, co sql server dělá:</p><pre><code>if not exists (select 1 from sys.objects where type = 'fn' and name = 'fn\_myfunc') begin declare @sql nvarchar(max); set @sql = n'create function ...'; exec sp\_executesql @sql; end </code></pre><p>nebo můžete říct:</p><pre><code>begin try drop function dbo.fn\_myfunc; end try begin catch print 'function did not exist.'; end catch go create function... </code></pre><p>nebo můžete jen říct:</p><pre><code>drop function dbo.fn\_myfunc; go create function... </code></pre><p>(zde se zobrazí chybová zpráva, pokud funkce již neexistuje, ale skript bude pokračovat od příštího go, takže ať už kapka pracovala nebo ne, bude funkce stále vytvořena (znovu).)</p><p>pokud funkci zrušíte a znovu ji vytvoříte, ztratíte také oprávnění a informace o závislostech.</p> <p>příkaz <code>merge</code> má složitou syntaxi a ještě složitější implementaci, ale v zásadě jde o spojení dvou tabulek, filtrování dolů na řádky, které je třeba změnit (vložit, aktualizovat nebo smazat), a poté provést požadované změny. vzhledem k těmto vzorovým údajům:</p><pre><code>declare @categoryitem as table ( categoryid integer not null, itemid integer not null, primary key (categoryid, itemid), unique (itemid, categoryid) ); declare @datasource as table ( categoryid integer not null, itemid integer not null primary key (categoryid, itemid) ); insert @categoryitem (categoryid, itemid) values (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 5), (3, 6), (4, 5); insert @datasource (categoryid, itemid) values (2, 2); </code></pre><p><strong> cíl </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 2 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 3 ║ ║ 3 ║ 5 ║ ║ 4 ║ 5 ║ ║ 3 ║ 6 ║ ╚════════════╩════════╝ </code></pre><p><strong> zdroj </strong></p><pre><code>╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>požadovaným výsledkem je nahrazení dat v cíli daty ze zdroje, ale pouze pro <code>categoryid = 2</code>. po výše uvedeném popisu <code>merge</code> bychom měli napsat dotaz, který spojuje zdroj a cíl pouze na klíče, a filtrovat řádky pouze v klauzulích <code>when</code>:</p><pre><code>merge into @categoryitem as target using @datasource as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by source and target.categoryid = 2 then delete when not matched by target and source.categoryid = 2 then insert (categoryid, itemid) values (categoryid, itemid) output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>to dává následující výsledky:</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 1 ║ 1 ║ ║ 1 ║ 2 ║ ║ 1 ║ 3 ║ ║ 2 ║ 2 ║ ║ 3 ║ 5 ║ ║ 3 ║ 6 ║ ║ 4 ║ 5 ║ ╚════════════╩════════╝ </code></pre><p>realizační plán je: <img src="https://i.stack.imgur.com/fovhu.jpg" alt="merge plan"></p><p>všimněte si, že jsou obě tabulky plně naskenovány. můžeme to považovat za neefektivní, protože pouze řádky, kde <code>categoryid = 2</code> bude ovlivněno v cílové tabulce. zde přicházejí varování v books online. jeden chybný pokus o optimalizaci, aby se dotkl pouze nezbytných řádků v cíli, je:</p><pre><code>merge into @categoryitem as target using ( select categoryid, itemid from @datasource as ds where categoryid = 2 ) as source on source.itemid = target.itemid and target.categoryid = 2 when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>logika v klauzuli <code>on</code> je použita jako součást spojení. v tomto případě je spojení úplným vnějším spojením (viz <a href="http://technet.microsoft.com/en-us/library/bb522522%28v=sql.105%29.aspx">tento záznam books online</a> proč). použití kontroly kategorie 2 na cílových řádcích jako součásti vnějšího spojení nakonec povede k odstranění řádků s jinou hodnotou (protože neodpovídají zdroji):</p><pre><code>╔═════════╦════════════╦════════╗ ║ $action ║ categoryid ║ itemid ║ ╠═════════╬════════════╬════════╣ ║ delete ║ 1 ║ 1 ║ ║ delete ║ 1 ║ 2 ║ ║ delete ║ 1 ║ 3 ║ ║ delete ║ 2 ║ 1 ║ ║ insert ║ 2 ║ 2 ║ ║ delete ║ 2 ║ 3 ║ ║ delete ║ 3 ║ 5 ║ ║ delete ║ 3 ║ 6 ║ ║ delete ║ 4 ║ 5 ║ ╚═════════╩════════════╩════════╝ ╔════════════╦════════╗ ║ categoryid ║ itemid ║ ╠════════════╬════════╣ ║ 2 ║ 2 ║ ╚════════════╩════════╝ </code></pre><p>kořenová příčina je ze stejného důvodu, proč se predikáty chovají v klauzuli vnější spojení <code>on</code> odlišně, než když jsou specifikovány v klauzuli <code>where</code>. syntaxe <code>merge</code> (a implementace spojení v závislosti na zadaných klauzulích) jen ztěžují vidět, že tomu tak je.</p><p> <a href="http://technet.microsoft.com/en-us/library/bb510625%28v=sql.105%29.aspx">navádění v books online</a> (rozšířeno v položce <a href="http://technet.microsoft.com/en-us/library/cc879317%28v=sql.105%29.aspx">optimizing performance</a> ) nabízí navádění, které zajistí, že správná sémantika je vyjádřena pomocí syntaxe <code>merge</code>, aniž by uživatel nutně musel muset pochopit všechny podrobnosti implementace nebo zohlednit způsoby, kterými by optimalizátor mohl legitimně přeskupit věci z důvodů efektivnosti provádění.</p><p>dokumentace nabízí tři možné způsoby implementace časného filtrování:</p><p><strong> zadání podmínky filtrování v klauzuli <code>when</code> </strong> zaručuje správné výsledky, ale může znamenat, že více řádků je čteno a zpracováno ze zdroje a cíle tabulky, než je nezbytně nutné (viz první příklad).</p><p><strong> aktualizace prostřednictvím zobrazení </strong>, která obsahuje podmínku filtrování, také zaručuje správné výsledky (protože změněné řádky musí být přístupné pro aktualizaci prostřednictvím zobrazení), ale vyžaduje to vyhrazené zobrazení, které splňuje liché podmínky pro aktualizaci zobrazení.</p><p><strong> použití společného výrazu tabulky </strong> přináší podobné riziko při přidávání predikátů k klauzuli <code>on</code>, ale z poněkud odlišných důvodů. v mnoha případech to bude bezpečné, ale vyžaduje to odbornou analýzu prováděcího plánu, aby se to potvrdilo (a rozsáhlé praktické testování). například:</p><pre><code>with target as ( select * from @categoryitem where categoryid = 2 ) merge into target using ( select categoryid, itemid from @datasource where categoryid = 2 ) as source on source.itemid = target.itemid and source.categoryid = target.categoryid when not matched by target then insert (categoryid, itemid) values (categoryid, itemid) when not matched by source then delete output $action, isnull(inserted.categoryid, deleted.categoryid) as categoryid, isnull(inserted.itemid, deleted.itemid) as itemid ; </code></pre><p>výsledkem jsou správné výsledky (neopakované) s optimálnějším plánem:</p><p><img src="https://i.stack.imgur.com/tazmk.jpg" alt="merge plan 2"></p><p>plán čte pouze řádky pro kategorii 2 z cílové tabulky. to může být důležitým hlediskem výkonu, pokud je cílová tabulka velká, ale je příliš snadné tuto chybu získat pomocí syntaxe <code>merge</code>.</p><p>někdy je snazší zapsat <code>merge</code> jako samostatné operace dml. tento přístup může dokonce <strong> vést lépe </strong> než jediný <code>merge</code>, což je skutečnost, která lidi často překvapuje.</p><pre><code>delete ci from @categoryitem as ci where ci.categoryid = 2 and not exists ( select 1 from @datasource as ds where ds.itemid = ci.itemid and ds.categoryid = ci.categoryid ); insert @categoryitem select ds.categoryid, ds.itemid from @datasource as ds where ds.categoryid = 2; </code></pre> <p>ne, neexportuje indexy. indexy se znovu vytvoří po načtení mysqldump zpět do mysql. možnosti, které jste našli „--disable-keys“, způsobí, že mysqldump něco napíše před načtením tabulky pomocí inserts:</p><pre><code>drop table if exists `tblaccountlinks`; set @saved\_cs\_client = @@character\_set\_client; set character\_set\_client = utf8; create table `tblaccountlinks` ( `id` int(11) not null auto\_increment, `firmno` varchar(10) not null, `customerno` varchar(20) not null, `accountno` varchar(20) not null, `linktype` smallint(6) not null, `accesslevel` smallint(6) not null, `status` smallint(6) not null, `createdon` datetime not null, primary key (`id`) ) engine=innodb auto\_increment=27023 default charset=latin1; set character\_set\_client = @saved\_cs\_client; -- -- dumping data for table `tblaccountlinks` -- lock tables `tblaccountlinks` write; /*!40000 alter table `tblaccountlinks` disable keys */; insert into `tblaccountlinks` values (1,'f0001','c001','t00000001',1,2,1,'2008-06-30 07:55:43'),(2,' f0001','c001','t00000002',2,2,1,'2008-06-30 07:55:43'),(3,'f0001','c002','27601012',1,2,1,'2008-06-3 ... </code></pre><p>řádek za lock tables je</p><pre><code>/*!40000 alter table `tblaccountlinks` disable keys */; </code></pre><p>to je to, co volba --disable-keys vloží do mysqldump.</p><p>také je to vloženo po dokončení všech vložek</p><pre><code>/*!40000 alter table `tblaccountlinks` enable keys */; unlock tables; </code></pre><p>caveat # 1</p><blockquote> <p>disable keys a enable keys byly implementovány tak, aby zakázaly opakované načítání nonunique indexů, zatímco se obnovuje tabulka. primární klíče a jedinečné klíče nejsou deaktivovány. jsou načteny ve stejnou chvíli, ve které jsou vložky. jakmile enable keys, nonunique indexy jsou znovu sestaveny tříděním (nebo pomocí mezipaměti myisam není dostatek dostupné paměti)</p> <p>bohužel funkce disable keys a enable keys funguje pouze pro tabulky myisam, ne pro innodb.</p> </blockquote><p>caveat # 2</p><p>nemusíte --disable-keys. mohli byste je zakázat zakázat keys (není určena žádná hříčka) pomocí --skip-disable-keys:</p><pre><code> -k, --disable-keys '/*!40000 alter table tb\_name disable keys */; and '/*!40000 alter table tb\_name enable keys */; will be put in the output. (defaults to on; use --skip-disable-keys to disable.) </code></pre><p>to by mohlo mít za následek pomalejší načtení a potenciální posunutí indexových stránek pro neunikové indexy.</p><p>caveat # 3</p><p>můžete vypsat skutečné tabulkové prostory innodb (mysql 5.5.12)</p><pre><code> -y, --all-tablespaces dump all the tablespaces. -y, --no-tablespaces do not dump any tablespace information. </code></pre>