summaryrefslogtreecommitdiff
path: root/Docs/manual.de.texi
blob: 01d1b008ebee4b767471333fb2a1dd889594771e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
3936
3937
3938
3939
3940
3941
3942
3943
3944
3945
3946
3947
3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055
5056
5057
5058
5059
5060
5061
5062
5063
5064
5065
5066
5067
5068
5069
5070
5071
5072
5073
5074
5075
5076
5077
5078
5079
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
5104
5105
5106
5107
5108
5109
5110
5111
5112
5113
5114
5115
5116
5117
5118
5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
5236
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
5409
5410
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
5428
5429
5430
5431
5432
5433
5434
5435
5436
5437
5438
5439
5440
5441
5442
5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
5671
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
5735
5736
5737
5738
5739
5740
5741
5742
5743
5744
5745
5746
5747
5748
5749
5750
5751
5752
5753
5754
5755
5756
5757
5758
5759
5760
5761
5762
5763
5764
5765
5766
5767
5768
5769
5770
5771
5772
5773
5774
5775
5776
5777
5778
5779
5780
5781
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792
5793
5794
5795
5796
5797
5798
5799
5800
5801
5802
5803
5804
5805
5806
5807
5808
5809
5810
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835
5836
5837
5838
5839
5840
5841
5842
5843
5844
5845
5846
5847
5848
5849
5850
5851
5852
5853
5854
5855
5856
5857
5858
5859
5860
5861
5862
5863
5864
5865
5866
5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
6103
6104
6105
6106
6107
6108
6109
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119
6120
6121
6122
6123
6124
6125
6126
6127
6128
6129
6130
6131
6132
6133
6134
6135
6136
6137
6138
6139
6140
6141
6142
6143
6144
6145
6146
6147
6148
6149
6150
6151
6152
6153
6154
6155
6156
6157
6158
6159
6160
6161
6162
6163
6164
6165
6166
6167
6168
6169
6170
6171
6172
6173
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187
6188
6189
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6205
6206
6207
6208
6209
6210
6211
6212
6213
6214
6215
6216
6217
6218
6219
6220
6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235
6236
6237
6238
6239
6240
6241
6242
6243
6244
6245
6246
6247
6248
6249
6250
6251
6252
6253
6254
6255
6256
6257
6258
6259
6260
6261
6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
6277
6278
6279
6280
6281
6282
6283
6284
6285
6286
6287
6288
6289
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299
6300
6301
6302
6303
6304
6305
6306
6307
6308
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6334
6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
6362
6363
6364
6365
6366
6367
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397
6398
6399
6400
6401
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411
6412
6413
6414
6415
6416
6417
6418
6419
6420
6421
6422
6423
6424
6425
6426
6427
6428
6429
6430
6431
6432
6433
6434
6435
6436
6437
6438
6439
6440
6441
6442
6443
6444
6445
6446
6447
6448
6449
6450
6451
6452
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485
6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502
6503
6504
6505
6506
6507
6508
6509
6510
6511
6512
6513
6514
6515
6516
6517
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538
6539
6540
6541
6542
6543
6544
6545
6546
6547
6548
6549
6550
6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605
6606
6607
6608
6609
6610
6611
6612
6613
6614
6615
6616
6617
6618
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642
6643
6644
6645
6646
6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
6662
6663
6664
6665
6666
6667
6668
6669
6670
6671
6672
6673
6674
6675
6676
6677
6678
6679
6680
6681
6682
6683
6684
6685
6686
6687
6688
6689
6690
6691
6692
6693
6694
6695
6696
6697
6698
6699
6700
6701
6702
6703
6704
6705
6706
6707
6708
6709
6710
6711
6712
6713
6714
6715
6716
6717
6718
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
6747
6748
6749
6750
6751
6752
6753
6754
6755
6756
6757
6758
6759
6760
6761
6762
6763
6764
6765
6766
6767
6768
6769
6770
6771
6772
6773
6774
6775
6776
6777
6778
6779
6780
6781
6782
6783
6784
6785
6786
6787
6788
6789
6790
6791
6792
6793
6794
6795
6796
6797
6798
6799
6800
6801
6802
6803
6804
6805
6806
6807
6808
6809
6810
6811
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833
6834
6835
6836
6837
6838
6839
6840
6841
6842
6843
6844
6845
6846
6847
6848
6849
6850
6851
6852
6853
6854
6855
6856
6857
6858
6859
6860
6861
6862
6863
6864
6865
6866
6867
6868
6869
6870
6871
6872
6873
6874
6875
6876
6877
6878
6879
6880
6881
6882
6883
6884
6885
6886
6887
6888
6889
6890
6891
6892
6893
6894
6895
6896
6897
6898
6899
6900
6901
6902
6903
6904
6905
6906
6907
6908
6909
6910
6911
6912
6913
6914
6915
6916
6917
6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960
6961
6962
6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
6987
6988
6989
6990
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
7009
7010
7011
7012
7013
7014
7015
7016
7017
7018
7019
7020
7021
7022
7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
7049
7050
7051
7052
7053
7054
7055
7056
7057
7058
7059
7060
7061
7062
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
7082
7083
7084
7085
7086
7087
7088
7089
7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
7106
7107
7108
7109
7110
7111
7112
7113
7114
7115
7116
7117
7118
7119
7120
7121
7122
7123
7124
7125
7126
7127
7128
7129
7130
7131
7132
7133
7134
7135
7136
7137
7138
7139
7140
7141
7142
7143
7144
7145
7146
7147
7148
7149
7150
7151
7152
7153
7154
7155
7156
7157
7158
7159
7160
7161
7162
7163
7164
7165
7166
7167
7168
7169
7170
7171
7172
7173
7174
7175
7176
7177
7178
7179
7180
7181
7182
7183
7184
7185
7186
7187
7188
7189
7190
7191
7192
7193
7194
7195
7196
7197
7198
7199
7200
7201
7202
7203
7204
7205
7206
7207
7208
7209
7210
7211
7212
7213
7214
7215
7216
7217
7218
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
7244
7245
7246
7247
7248
7249
7250
7251
7252
7253
7254
7255
7256
7257
7258
7259
7260
7261
7262
7263
7264
7265
7266
7267
7268
7269
7270
7271
7272
7273
7274
7275
7276
7277
7278
7279
7280
7281
7282
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303
7304
7305
7306
7307
7308
7309
7310
7311
7312
7313
7314
7315
7316
7317
7318
7319
7320
7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
7349
7350
7351
7352
7353
7354
7355
7356
7357
7358
7359
7360
7361
7362
7363
7364
7365
7366
7367
7368
7369
7370
7371
7372
7373
7374
7375
7376
7377
7378
7379
7380
7381
7382
7383
7384
7385
7386
7387
7388
7389
7390
7391
7392
7393
7394
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486
7487
7488
7489
7490
7491
7492
7493
7494
7495
7496
7497
7498
7499
7500
7501
7502
7503
7504
7505
7506
7507
7508
7509
7510
7511
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7525
7526
7527
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
7587
7588
7589
7590
7591
7592
7593
7594
7595
7596
7597
7598
7599
7600
7601
7602
7603
7604
7605
7606
7607
7608
7609
7610
7611
7612
7613
7614
7615
7616
7617
7618
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633
7634
7635
7636
7637
7638
7639
7640
7641
7642
7643
7644
7645
7646
7647
7648
7649
7650
7651
7652
7653
7654
7655
7656
7657
7658
7659
7660
7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
7676
7677
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
8414
8415
8416
8417
8418
8419
8420
8421
8422
8423
8424
8425
8426
8427
8428
8429
8430
8431
8432
8433
8434
8435
8436
8437
8438
8439
8440
8441
8442
8443
8444
8445
8446
8447
8448
8449
8450
8451
8452
8453
8454
8455
8456
8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467
8468
8469
8470
8471
8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
8508
8509
8510
8511
8512
8513
8514
8515
8516
8517
8518
8519
8520
8521
8522
8523
8524
8525
8526
8527
8528
8529
8530
8531
8532
8533
8534
8535
8536
8537
8538
8539
8540
8541
8542
8543
8544
8545
8546
8547
8548
8549
8550
8551
8552
8553
8554
8555
8556
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
8572
8573
8574
8575
8576
8577
8578
8579
8580
8581
8582
8583
8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
8599
8600
8601
8602
8603
8604
8605
8606
8607
8608
8609
8610
8611
8612
8613
8614
8615
8616
8617
8618
8619
8620
8621
8622
8623
8624
8625
8626
8627
8628
8629
8630
8631
8632
8633
8634
8635
8636
8637
8638
8639
8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657
8658
8659
8660
8661
8662
8663
8664
8665
8666
8667
8668
8669
8670
8671
8672
8673
8674
8675
8676
8677
8678
8679
8680
8681
8682
8683
8684
8685
8686
8687
8688
8689
8690
8691
8692
8693
8694
8695
8696
8697
8698
8699
8700
8701
8702
8703
8704
8705
8706
8707
8708
8709
8710
8711
8712
8713
8714
8715
8716
8717
8718
8719
8720
8721
8722
8723
8724
8725
8726
8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
8763
8764
8765
8766
8767
8768
8769
8770
8771
8772
8773
8774
8775
8776
8777
8778
8779
8780
8781
8782
8783
8784
8785
8786
8787
8788
8789
8790
8791
8792
8793
8794
8795
8796
8797
8798
8799
8800
8801
8802
8803
8804
8805
8806
8807
8808
8809
8810
8811
8812
8813
8814
8815
8816
8817
8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
8846
8847
8848
8849
8850
8851
8852
8853
8854
8855
8856
8857
8858
8859
8860
8861
8862
8863
8864
8865
8866
8867
8868
8869
8870
8871
8872
8873
8874
8875
8876
8877
8878
8879
8880
8881
8882
8883
8884
8885
8886
8887
8888
8889
8890
8891
8892
8893
8894
8895
8896
8897
8898
8899
8900
8901
8902
8903
8904
8905
8906
8907
8908
8909
8910
8911
8912
8913
8914
8915
8916
8917
8918
8919
8920
8921
8922
8923
8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
8946
8947
8948
8949
8950
8951
8952
8953
8954
8955
8956
8957
8958
8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
8984
8985
8986
8987
8988
8989
8990
8991
8992
8993
8994
8995
8996
8997
8998
8999
9000
9001
9002
9003
9004
9005
9006
9007
9008
9009
9010
9011
9012
9013
9014
9015
9016
9017
9018
9019
9020
9021
9022
9023
9024
9025
9026
9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
9046
9047
9048
9049
9050
9051
9052
9053
9054
9055
9056
9057
9058
9059
9060
9061
9062
9063
9064
9065
9066
9067
9068
9069
9070
9071
9072
9073
9074
9075
9076
9077
9078
9079
9080
9081
9082
9083
9084
9085
9086
9087
9088
9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
9104
9105
9106
9107
9108
9109
9110
9111
9112
9113
9114
9115
9116
9117
9118
9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
9165
9166
9167
9168
9169
9170
9171
9172
9173
9174
9175
9176
9177
9178
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
9286
9287
9288
9289
9290
9291
9292
9293
9294
9295
9296
9297
9298
9299
9300
9301
9302
9303
9304
9305
9306
9307
9308
9309
9310
9311
9312
9313
9314
9315
9316
9317
9318
9319
9320
9321
9322
9323
9324
9325
9326
9327
9328
9329
9330
9331
9332
9333
9334
9335
9336
9337
9338
9339
9340
9341
9342
9343
9344
9345
9346
9347
9348
9349
9350
9351
9352
9353
9354
9355
9356
9357
9358
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
9384
9385
9386
9387
9388
9389
9390
9391
9392
9393
9394
9395
9396
9397
9398
9399
9400
9401
9402
9403
9404
9405
9406
9407
9408
9409
9410
9411
9412
9413
9414
9415
9416
9417
9418
9419
9420
9421
9422
9423
9424
9425
9426
9427
9428
9429
9430
9431
9432
9433
9434
9435
9436
9437
9438
9439
9440
9441
9442
9443
9444
9445
9446
9447
9448
9449
9450
9451
9452
9453
9454
9455
9456
9457
9458
9459
9460
9461
9462
9463
9464
9465
9466
9467
9468
9469
9470
9471
9472
9473
9474
9475
9476
9477
9478
9479
9480
9481
9482
9483
9484
9485
9486
9487
9488
9489
9490
9491
9492
9493
9494
9495
9496
9497
9498
9499
9500
9501
9502
9503
9504
9505
9506
9507
9508
9509
9510
9511
9512
9513
9514
9515
9516
9517
9518
9519
9520
9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535
9536
9537
9538
9539
9540
9541
9542
9543
9544
9545
9546
9547
9548
9549
9550
9551
9552
9553
9554
9555
9556
9557
9558
9559
9560
9561
9562
9563
9564
9565
9566
9567
9568
9569
9570
9571
9572
9573
9574
9575
9576
9577
9578
9579
9580
9581
9582
9583
9584
9585
9586
9587
9588
9589
9590
9591
9592
9593
9594
9595
9596
9597
9598
9599
9600
9601
9602
9603
9604
9605
9606
9607
9608
9609
9610
9611
9612
9613
9614
9615
9616
9617
9618
9619
9620
9621
9622
9623
9624
9625
9626
9627
9628
9629
9630
9631
9632
9633
9634
9635
9636
9637
9638
9639
9640
9641
9642
9643
9644
9645
9646
9647
9648
9649
9650
9651
9652
9653
9654
9655
9656
9657
9658
9659
9660
9661
9662
9663
9664
9665
9666
9667
9668
9669
9670
9671
9672
9673
9674
9675
9676
9677
9678
9679
9680
9681
9682
9683
9684
9685
9686
9687
9688
9689
9690
9691
9692
9693
9694
9695
9696
9697
9698
9699
9700
9701
9702
9703
9704
9705
9706
9707
9708
9709
9710
9711
9712
9713
9714
9715
9716
9717
9718
9719
9720
9721
9722
9723
9724
9725
9726
9727
9728
9729
9730
9731
9732
9733
9734
9735
9736
9737
9738
9739
9740
9741
9742
9743
9744
9745
9746
9747
9748
9749
9750
9751
9752
9753
9754
9755
9756
9757
9758
9759
9760
9761
9762
9763
9764
9765
9766
9767
9768
9769
9770
9771
9772
9773
9774
9775
9776
9777
9778
9779
9780
9781
9782
9783
9784
9785
9786
9787
9788
9789
9790
9791
9792
9793
9794
9795
9796
9797
9798
9799
9800
9801
9802
9803
9804
9805
9806
9807
9808
9809
9810
9811
9812
9813
9814
9815
9816
9817
9818
9819
9820
9821
9822
9823
9824
9825
9826
9827
9828
9829
9830
9831
9832
9833
9834
9835
9836
9837
9838
9839
9840
9841
9842
9843
9844
9845
9846
9847
9848
9849
9850
9851
9852
9853
9854
9855
9856
9857
9858
9859
9860
9861
9862
9863
9864
9865
9866
9867
9868
9869
9870
9871
9872
9873
9874
9875
9876
9877
9878
9879
9880
9881
9882
9883
9884
9885
9886
9887
9888
9889
9890
9891
9892
9893
9894
9895
9896
9897
9898
9899
9900
9901
9902
9903
9904
9905
9906
9907
9908
9909
9910
9911
9912
9913
9914
9915
9916
9917
9918
9919
9920
9921
9922
9923
9924
9925
9926
9927
9928
9929
9930
9931
9932
9933
9934
9935
9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950
9951
9952
9953
9954
9955
9956
9957
9958
9959
9960
9961
9962
9963
9964
9965
9966
9967
9968
9969
9970
9971
9972
9973
9974
9975
9976
9977
9978
9979
9980
9981
9982
9983
9984
9985
9986
9987
9988
9989
9990
9991
9992
9993
9994
9995
9996
9997
9998
9999
10000
10001
10002
10003
10004
10005
10006
10007
10008
10009
10010
10011
10012
10013
10014
10015
10016
10017
10018
10019
10020
10021
10022
10023
10024
10025
10026
10027
10028
10029
10030
10031
10032
10033
10034
10035
10036
10037
10038
10039
10040
10041
10042
10043
10044
10045
10046
10047
10048
10049
10050
10051
10052
10053
10054
10055
10056
10057
10058
10059
10060
10061
10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
10080
10081
10082
10083
10084
10085
10086
10087
10088
10089
10090
10091
10092
10093
10094
10095
10096
10097
10098
10099
10100
10101
10102
10103
10104
10105
10106
10107
10108
10109
10110
10111
10112
10113
10114
10115
10116
10117
10118
10119
10120
10121
10122
10123
10124
10125
10126
10127
10128
10129
10130
10131
10132
10133
10134
10135
10136
10137
10138
10139
10140
10141
10142
10143
10144
10145
10146
10147
10148
10149
10150
10151
10152
10153
10154
10155
10156
10157
10158
10159
10160
10161
10162
10163
10164
10165
10166
10167
10168
10169
10170
10171
10172
10173
10174
10175
10176
10177
10178
10179
10180
10181
10182
10183
10184
10185
10186
10187
10188
10189
10190
10191
10192
10193
10194
10195
10196
10197
10198
10199
10200
10201
10202
10203
10204
10205
10206
10207
10208
10209
10210
10211
10212
10213
10214
10215
10216
10217
10218
10219
10220
10221
10222
10223
10224
10225
10226
10227
10228
10229
10230
10231
10232
10233
10234
10235
10236
10237
10238
10239
10240
10241
10242
10243
10244
10245
10246
10247
10248
10249
10250
10251
10252
10253
10254
10255
10256
10257
10258
10259
10260
10261
10262
10263
10264
10265
10266
10267
10268
10269
10270
10271
10272
10273
10274
10275
10276
10277
10278
10279
10280
10281
10282
10283
10284
10285
10286
10287
10288
10289
10290
10291
10292
10293
10294
10295
10296
10297
10298
10299
10300
10301
10302
10303
10304
10305
10306
10307
10308
10309
10310
10311
10312
10313
10314
10315
10316
10317
10318
10319
10320
10321
10322
10323
10324
10325
10326
10327
10328
10329
10330
10331
10332
10333
10334
10335
10336
10337
10338
10339
10340
10341
10342
10343
10344
10345
10346
10347
10348
10349
10350
10351
10352
10353
10354
10355
10356
10357
10358
10359
10360
10361
10362
10363
10364
10365
10366
10367
10368
10369
10370
10371
10372
10373
10374
10375
10376
10377
10378
10379
10380
10381
10382
10383
10384
10385
10386
10387
10388
10389
10390
10391
10392
10393
10394
10395
10396
10397
10398
10399
10400
10401
10402
10403
10404
10405
10406
10407
10408
10409
10410
10411
10412
10413
10414
10415
10416
10417
10418
10419
10420
10421
10422
10423
10424
10425
10426
10427
10428
10429
10430
10431
10432
10433
10434
10435
10436
10437
10438
10439
10440
10441
10442
10443
10444
10445
10446
10447
10448
10449
10450
10451
10452
10453
10454
10455
10456
10457
10458
10459
10460
10461
10462
10463
10464
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490
10491
10492
10493
10494
10495
10496
10497
10498
10499
10500
10501
10502
10503
10504
10505
10506
10507
10508
10509
10510
10511
10512
10513
10514
10515
10516
10517
10518
10519
10520
10521
10522
10523
10524
10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541
10542
10543
10544
10545
10546
10547
10548
10549
10550
10551
10552
10553
10554
10555
10556
10557
10558
10559
10560
10561
10562
10563
10564
10565
10566
10567
10568
10569
10570
10571
10572
10573
10574
10575
10576
10577
10578
10579
10580
10581
10582
10583
10584
10585
10586
10587
10588
10589
10590
10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624
10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720
10721
10722
10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
10733
10734
10735
10736
10737
10738
10739
10740
10741
10742
10743
10744
10745
10746
10747
10748
10749
10750
10751
10752
10753
10754
10755
10756
10757
10758
10759
10760
10761
10762
10763
10764
10765
10766
10767
10768
10769
10770
10771
10772
10773
10774
10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806
10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851
10852
10853
10854
10855
10856
10857
10858
10859
10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871
10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
10897
10898
10899
10900
10901
10902
10903
10904
10905
10906
10907
10908
10909
10910
10911
10912
10913
10914
10915
10916
10917
10918
10919
10920
10921
10922
10923
10924
10925
10926
10927
10928
10929
10930
10931
10932
10933
10934
10935
10936
10937
10938
10939
10940
10941
10942
10943
10944
10945
10946
10947
10948
10949
10950
10951
10952
10953
10954
10955
10956
10957
10958
10959
10960
10961
10962
10963
10964
10965
10966
10967
10968
10969
10970
10971
10972
10973
10974
10975
10976
10977
10978
10979
10980
10981
10982
10983
10984
10985
10986
10987
10988
10989
10990
10991
10992
10993
10994
10995
10996
10997
10998
10999
11000
11001
11002
11003
11004
11005
11006
11007
11008
11009
11010
11011
11012
11013
11014
11015
11016
11017
11018
11019
11020
11021
11022
11023
11024
11025
11026
11027
11028
11029
11030
11031
11032
11033
11034
11035
11036
11037
11038
11039
11040
11041
11042
11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
11063
11064
11065
11066
11067
11068
11069
11070
11071
11072
11073
11074
11075
11076
11077
11078
11079
11080
11081
11082
11083
11084
11085
11086
11087
11088
11089
11090
11091
11092
11093
11094
11095
11096
11097
11098
11099
11100
11101
11102
11103
11104
11105
11106
11107
11108
11109
11110
11111
11112
11113
11114
11115
11116
11117
11118
11119
11120
11121
11122
11123
11124
11125
11126
11127
11128
11129
11130
11131
11132
11133
11134
11135
11136
11137
11138
11139
11140
11141
11142
11143
11144
11145
11146
11147
11148
11149
11150
11151
11152
11153
11154
11155
11156
11157
11158
11159
11160
11161
11162
11163
11164
11165
11166
11167
11168
11169
11170
11171
11172
11173
11174
11175
11176
11177
11178
11179
11180
11181
11182
11183
11184
11185
11186
11187
11188
11189
11190
11191
11192
11193
11194
11195
11196
11197
11198
11199
11200
11201
11202
11203
11204
11205
11206
11207
11208
11209
11210
11211
11212
11213
11214
11215
11216
11217
11218
11219
11220
11221
11222
11223
11224
11225
11226
11227
11228
11229
11230
11231
11232
11233
11234
11235
11236
11237
11238
11239
11240
11241
11242
11243
11244
11245
11246
11247
11248
11249
11250
11251
11252
11253
11254
11255
11256
11257
11258
11259
11260
11261
11262
11263
11264
11265
11266
11267
11268
11269
11270
11271
11272
11273
11274
11275
11276
11277
11278
11279
11280
11281
11282
11283
11284
11285
11286
11287
11288
11289
11290
11291
11292
11293
11294
11295
11296
11297
11298
11299
11300
11301
11302
11303
11304
11305
11306
11307
11308
11309
11310
11311
11312
11313
11314
11315
11316
11317
11318
11319
11320
11321
11322
11323
11324
11325
11326
11327
11328
11329
11330
11331
11332
11333
11334
11335
11336
11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
11356
11357
11358
11359
11360
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
11378
11379
11380
11381
11382
11383
11384
11385
11386
11387
11388
11389
11390
11391
11392
11393
11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
11413
11414
11415
11416
11417
11418
11419
11420
11421
11422
11423
11424
11425
11426
11427
11428
11429
11430
11431
11432
11433
11434
11435
11436
11437
11438
11439
11440
11441
11442
11443
11444
11445
11446
11447
11448
11449
11450
11451
11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
11469
11470
11471
11472
11473
11474
11475
11476
11477
11478
11479
11480
11481
11482
11483
11484
11485
11486
11487
11488
11489
11490
11491
11492
11493
11494
11495
11496
11497
11498
11499
11500
11501
11502
11503
11504
11505
11506
11507
11508
11509
11510
11511
11512
11513
11514
11515
11516
11517
11518
11519
11520
11521
11522
11523
11524
11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
11543
11544
11545
11546
11547
11548
11549
11550
11551
11552
11553
11554
11555
11556
11557
11558
11559
11560
11561
11562
11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
11579
11580
11581
11582
11583
11584
11585
11586
11587
11588
11589
11590
11591
11592
11593
11594
11595
11596
11597
11598
11599
11600
11601
11602
11603
11604
11605
11606
11607
11608
11609
11610
11611
11612
11613
11614
11615
11616
11617
11618
11619
11620
11621
11622
11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
11639
11640
11641
11642
11643
11644
11645
11646
11647
11648
11649
11650
11651
11652
11653
11654
11655
11656
11657
11658
11659
11660
11661
11662
11663
11664
11665
11666
11667
11668
11669
11670
11671
11672
11673
11674
11675
11676
11677
11678
11679
11680
11681
11682
11683
11684
11685
11686
11687
11688
11689
11690
11691
11692
11693
11694
11695
11696
11697
11698
11699
11700
11701
11702
11703
11704
11705
11706
11707
11708
11709
11710
11711
11712
11713
11714
11715
11716
11717
11718
11719
11720
11721
11722
11723
11724
11725
11726
11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
11740
11741
11742
11743
11744
11745
11746
11747
11748
11749
11750
11751
11752
11753
11754
11755
11756
11757
11758
11759
11760
11761
11762
11763
11764
11765
11766
11767
11768
11769
11770
11771
11772
11773
11774
11775
11776
11777
11778
11779
11780
11781
11782
11783
11784
11785
11786
11787
11788
11789
11790
11791
11792
11793
11794
11795
11796
11797
11798
11799
11800
11801
11802
11803
11804
11805
11806
11807
11808
11809
11810
11811
11812
11813
11814
11815
11816
11817
11818
11819
11820
11821
11822
11823
11824
11825
11826
11827
11828
11829
11830
11831
11832
11833
11834
11835
11836
11837
11838
11839
11840
11841
11842
11843
11844
11845
11846
11847
11848
11849
11850
11851
11852
11853
11854
11855
11856
11857
11858
11859
11860
11861
11862
11863
11864
11865
11866
11867
11868
11869
11870
11871
11872
11873
11874
11875
11876
11877
11878
11879
11880
11881
11882
11883
11884
11885
11886
11887
11888
11889
11890
11891
11892
11893
11894
11895
11896
11897
11898
11899
11900
11901
11902
11903
11904
11905
11906
11907
11908
11909
11910
11911
11912
11913
11914
11915
11916
11917
11918
11919
11920
11921
11922
11923
11924
11925
11926
11927
11928
11929
11930
11931
11932
11933
11934
11935
11936
11937
11938
11939
11940
11941
11942
11943
11944
11945
11946
11947
11948
11949
11950
11951
11952
11953
11954
11955
11956
11957
11958
11959
11960
11961
11962
11963
11964
11965
11966
11967
11968
11969
11970
11971
11972
11973
11974
11975
11976
11977
11978
11979
11980
11981
11982
11983
11984
11985
11986
11987
11988
11989
11990
11991
11992
11993
11994
11995
11996
11997
11998
11999
12000
12001
12002
12003
12004
12005
12006
12007
12008
12009
12010
12011
12012
12013
12014
12015
12016
12017
12018
12019
12020
12021
12022
12023
12024
12025
12026
12027
12028
12029
12030
12031
12032
12033
12034
12035
12036
12037
12038
12039
12040
12041
12042
12043
12044
12045
12046
12047
12048
12049
12050
12051
12052
12053
12054
12055
12056
12057
12058
12059
12060
12061
12062
12063
12064
12065
12066
12067
12068
12069
12070
12071
12072
12073
12074
12075
12076
12077
12078
12079
12080
12081
12082
12083
12084
12085
12086
12087
12088
12089
12090
12091
12092
12093
12094
12095
12096
12097
12098
12099
12100
12101
12102
12103
12104
12105
12106
12107
12108
12109
12110
12111
12112
12113
12114
12115
12116
12117
12118
12119
12120
12121
12122
12123
12124
12125
12126
12127
12128
12129
12130
12131
12132
12133
12134
12135
12136
12137
12138
12139
12140
12141
12142
12143
12144
12145
12146
12147
12148
12149
12150
12151
12152
12153
12154
12155
12156
12157
12158
12159
12160
12161
12162
12163
12164
12165
12166
12167
12168
12169
12170
12171
12172
12173
12174
12175
12176
12177
12178
12179
12180
12181
12182
12183
12184
12185
12186
12187
12188
12189
12190
12191
12192
12193
12194
12195
12196
12197
12198
12199
12200
12201
12202
12203
12204
12205
12206
12207
12208
12209
12210
12211
12212
12213
12214
12215
12216
12217
12218
12219
12220
12221
12222
12223
12224
12225
12226
12227
12228
12229
12230
12231
12232
12233
12234
12235
12236
12237
12238
12239
12240
12241
12242
12243
12244
12245
12246
12247
12248
12249
12250
12251
12252
12253
12254
12255
12256
12257
12258
12259
12260
12261
12262
12263
12264
12265
12266
12267
12268
12269
12270
12271
12272
12273
12274
12275
12276
12277
12278
12279
12280
12281
12282
12283
12284
12285
12286
12287
12288
12289
12290
12291
12292
12293
12294
12295
12296
12297
12298
12299
12300
12301
12302
12303
12304
12305
12306
12307
12308
12309
12310
12311
12312
12313
12314
12315
12316
12317
12318
12319
12320
12321
12322
12323
12324
12325
12326
12327
12328
12329
12330
12331
12332
12333
12334
12335
12336
12337
12338
12339
12340
12341
12342
12343
12344
12345
12346
12347
12348
12349
12350
12351
12352
12353
12354
12355
12356
12357
12358
12359
12360
12361
12362
12363
12364
12365
12366
12367
12368
12369
12370
12371
12372
12373
12374
12375
12376
12377
12378
12379
12380
12381
12382
12383
12384
12385
12386
12387
12388
12389
12390
12391
12392
12393
12394
12395
12396
12397
12398
12399
12400
12401
12402
12403
12404
12405
12406
12407
12408
12409
12410
12411
12412
12413
12414
12415
12416
12417
12418
12419
12420
12421
12422
12423
12424
12425
12426
12427
12428
12429
12430
12431
12432
12433
12434
12435
12436
12437
12438
12439
12440
12441
12442
12443
12444
12445
12446
12447
12448
12449
12450
12451
12452
12453
12454
12455
12456
12457
12458
12459
12460
12461
12462
12463
12464
12465
12466
12467
12468
12469
12470
12471
12472
12473
12474
12475
12476
12477
12478
12479
12480
12481
12482
12483
12484
12485
12486
12487
12488
12489
12490
12491
12492
12493
12494
12495
12496
12497
12498
12499
12500
12501
12502
12503
12504
12505
12506
12507
12508
12509
12510
12511
12512
12513
12514
12515
12516
12517
12518
12519
12520
12521
12522
12523
12524
12525
12526
12527
12528
12529
12530
12531
12532
12533
12534
12535
12536
12537
12538
12539
12540
12541
12542
12543
12544
12545
12546
12547
12548
12549
12550
12551
12552
12553
12554
12555
12556
12557
12558
12559
12560
12561
12562
12563
12564
12565
12566
12567
12568
12569
12570
12571
12572
12573
12574
12575
12576
12577
12578
12579
12580
12581
12582
12583
12584
12585
12586
12587
12588
12589
12590
12591
12592
12593
12594
12595
12596
12597
12598
12599
12600
12601
12602
12603
12604
12605
12606
12607
12608
12609
12610
12611
12612
12613
12614
12615
12616
12617
12618
12619
12620
12621
12622
12623
12624
12625
12626
12627
12628
12629
12630
12631
12632
12633
12634
12635
12636
12637
12638
12639
12640
12641
12642
12643
12644
12645
12646
12647
12648
12649
12650
12651
12652
12653
12654
12655
12656
12657
12658
12659
12660
12661
12662
12663
12664
12665
12666
12667
12668
12669
12670
12671
12672
12673
12674
12675
12676
12677
12678
12679
12680
12681
12682
12683
12684
12685
12686
12687
12688
12689
12690
12691
12692
12693
12694
12695
12696
12697
12698
12699
12700
12701
12702
12703
12704
12705
12706
12707
12708
12709
12710
12711
12712
12713
12714
12715
12716
12717
12718
12719
12720
12721
12722
12723
12724
12725
12726
12727
12728
12729
12730
12731
12732
12733
12734
12735
12736
12737
12738
12739
12740
12741
12742
12743
12744
12745
12746
12747
12748
12749
12750
12751
12752
12753
12754
12755
12756
12757
12758
12759
12760
12761
12762
12763
12764
12765
12766
12767
12768
12769
12770
12771
12772
12773
12774
12775
12776
12777
12778
12779
12780
12781
12782
12783
12784
12785
12786
12787
12788
12789
12790
12791
12792
12793
12794
12795
12796
12797
12798
12799
12800
12801
12802
12803
12804
12805
12806
12807
12808
12809
12810
12811
12812
12813
12814
12815
12816
12817
12818
12819
12820
12821
12822
12823
12824
12825
12826
12827
12828
12829
12830
12831
12832
12833
12834
12835
12836
12837
12838
12839
12840
12841
12842
12843
12844
12845
12846
12847
12848
12849
12850
12851
12852
12853
12854
12855
12856
12857
12858
12859
12860
12861
12862
12863
12864
12865
12866
12867
12868
12869
12870
12871
12872
12873
12874
12875
12876
12877
12878
12879
12880
12881
12882
12883
12884
12885
12886
12887
12888
12889
12890
12891
12892
12893
12894
12895
12896
12897
12898
12899
12900
12901
12902
12903
12904
12905
12906
12907
12908
12909
12910
12911
12912
12913
12914
12915
12916
12917
12918
12919
12920
12921
12922
12923
12924
12925
12926
12927
12928
12929
12930
12931
12932
12933
12934
12935
12936
12937
12938
12939
12940
12941
12942
12943
12944
12945
12946
12947
12948
12949
12950
12951
12952
12953
12954
12955
12956
12957
12958
12959
12960
12961
12962
12963
12964
12965
12966
12967
12968
12969
12970
12971
12972
12973
12974
12975
12976
12977
12978
12979
12980
12981
12982
12983
12984
12985
12986
12987
12988
12989
12990
12991
12992
12993
12994
12995
12996
12997
12998
12999
13000
13001
13002
13003
13004
13005
13006
13007
13008
13009
13010
13011
13012
13013
13014
13015
13016
13017
13018
13019
13020
13021
13022
13023
13024
13025
13026
13027
13028
13029
13030
13031
13032
13033
13034
13035
13036
13037
13038
13039
13040
13041
13042
13043
13044
13045
13046
13047
13048
13049
13050
13051
13052
13053
13054
13055
13056
13057
13058
13059
13060
13061
13062
13063
13064
13065
13066
13067
13068
13069
13070
13071
13072
13073
13074
13075
13076
13077
13078
13079
13080
13081
13082
13083
13084
13085
13086
13087
13088
13089
13090
13091
13092
13093
13094
13095
13096
13097
13098
13099
13100
13101
13102
13103
13104
13105
13106
13107
13108
13109
13110
13111
13112
13113
13114
13115
13116
13117
13118
13119
13120
13121
13122
13123
13124
13125
13126
13127
13128
13129
13130
13131
13132
13133
13134
13135
13136
13137
13138
13139
13140
13141
13142
13143
13144
13145
13146
13147
13148
13149
13150
13151
13152
13153
13154
13155
13156
13157
13158
13159
13160
13161
13162
13163
13164
13165
13166
13167
13168
13169
13170
13171
13172
13173
13174
13175
13176
13177
13178
13179
13180
13181
13182
13183
13184
13185
13186
13187
13188
13189
13190
13191
13192
13193
13194
13195
13196
13197
13198
13199
13200
13201
13202
13203
13204
13205
13206
13207
13208
13209
13210
13211
13212
13213
13214
13215
13216
13217
13218
13219
13220
13221
13222
13223
13224
13225
13226
13227
13228
13229
13230
13231
13232
13233
13234
13235
13236
13237
13238
13239
13240
13241
13242
13243
13244
13245
13246
13247
13248
13249
13250
13251
13252
13253
13254
13255
13256
13257
13258
13259
13260
13261
13262
13263
13264
13265
13266
13267
13268
13269
13270
13271
13272
13273
13274
13275
13276
13277
13278
13279
13280
13281
13282
13283
13284
13285
13286
13287
13288
13289
13290
13291
13292
13293
13294
13295
13296
13297
13298
13299
13300
13301
13302
13303
13304
13305
13306
13307
13308
13309
13310
13311
13312
13313
13314
13315
13316
13317
13318
13319
13320
13321
13322
13323
13324
13325
13326
13327
13328
13329
13330
13331
13332
13333
13334
13335
13336
13337
13338
13339
13340
13341
13342
13343
13344
13345
13346
13347
13348
13349
13350
13351
13352
13353
13354
13355
13356
13357
13358
13359
13360
13361
13362
13363
13364
13365
13366
13367
13368
13369
13370
13371
13372
13373
13374
13375
13376
13377
13378
13379
13380
13381
13382
13383
13384
13385
13386
13387
13388
13389
13390
13391
13392
13393
13394
13395
13396
13397
13398
13399
13400
13401
13402
13403
13404
13405
13406
13407
13408
13409
13410
13411
13412
13413
13414
13415
13416
13417
13418
13419
13420
13421
13422
13423
13424
13425
13426
13427
13428
13429
13430
13431
13432
13433
13434
13435
13436
13437
13438
13439
13440
13441
13442
13443
13444
13445
13446
13447
13448
13449
13450
13451
13452
13453
13454
13455
13456
13457
13458
13459
13460
13461
13462
13463
13464
13465
13466
13467
13468
13469
13470
13471
13472
13473
13474
13475
13476
13477
13478
13479
13480
13481
13482
13483
13484
13485
13486
13487
13488
13489
13490
13491
13492
13493
13494
13495
13496
13497
13498
13499
13500
13501
13502
13503
13504
13505
13506
13507
13508
13509
13510
13511
13512
13513
13514
13515
13516
13517
13518
13519
13520
13521
13522
13523
13524
13525
13526
13527
13528
13529
13530
13531
13532
13533
13534
13535
13536
13537
13538
13539
13540
13541
13542
13543
13544
13545
13546
13547
13548
13549
13550
13551
13552
13553
13554
13555
13556
13557
13558
13559
13560
13561
13562
13563
13564
13565
13566
13567
13568
13569
13570
13571
13572
13573
13574
13575
13576
13577
13578
13579
13580
13581
13582
13583
13584
13585
13586
13587
13588
13589
13590
13591
13592
13593
13594
13595
13596
13597
13598
13599
13600
13601
13602
13603
13604
13605
13606
13607
13608
13609
13610
13611
13612
13613
13614
13615
13616
13617
13618
13619
13620
13621
13622
13623
13624
13625
13626
13627
13628
13629
13630
13631
13632
13633
13634
13635
13636
13637
13638
13639
13640
13641
13642
13643
13644
13645
13646
13647
13648
13649
13650
13651
13652
13653
13654
13655
13656
13657
13658
13659
13660
13661
13662
13663
13664
13665
13666
13667
13668
13669
13670
13671
13672
13673
13674
13675
13676
13677
13678
13679
13680
13681
13682
13683
13684
13685
13686
13687
13688
13689
13690
13691
13692
13693
13694
13695
13696
13697
13698
13699
13700
13701
13702
13703
13704
13705
13706
13707
13708
13709
13710
13711
13712
13713
13714
13715
13716
13717
13718
13719
13720
13721
13722
13723
13724
13725
13726
13727
13728
13729
13730
13731
13732
13733
13734
13735
13736
13737
13738
13739
13740
13741
13742
13743
13744
13745
13746
13747
13748
13749
13750
13751
13752
13753
13754
13755
13756
13757
13758
13759
13760
13761
13762
13763
13764
13765
13766
13767
13768
13769
13770
13771
13772
13773
13774
13775
13776
13777
13778
13779
13780
13781
13782
13783
13784
13785
13786
13787
13788
13789
13790
13791
13792
13793
13794
13795
13796
13797
13798
13799
13800
13801
13802
13803
13804
13805
13806
13807
13808
13809
13810
13811
13812
13813
13814
13815
13816
13817
13818
13819
13820
13821
13822
13823
13824
13825
13826
13827
13828
13829
13830
13831
13832
13833
13834
13835
13836
13837
13838
13839
13840
13841
13842
13843
13844
13845
13846
13847
13848
13849
13850
13851
13852
13853
13854
13855
13856
13857
13858
13859
13860
13861
13862
13863
13864
13865
13866
13867
13868
13869
13870
13871
13872
13873
13874
13875
13876
13877
13878
13879
13880
13881
13882
13883
13884
13885
13886
13887
13888
13889
13890
13891
13892
13893
13894
13895
13896
13897
13898
13899
13900
13901
13902
13903
13904
13905
13906
13907
13908
13909
13910
13911
13912
13913
13914
13915
13916
13917
13918
13919
13920
13921
13922
13923
13924
13925
13926
13927
13928
13929
13930
13931
13932
13933
13934
13935
13936
13937
13938
13939
13940
13941
13942
13943
13944
13945
13946
13947
13948
13949
13950
13951
13952
13953
13954
13955
13956
13957
13958
13959
13960
13961
13962
13963
13964
13965
13966
13967
13968
13969
13970
13971
13972
13973
13974
13975
13976
13977
13978
13979
13980
13981
13982
13983
13984
13985
13986
13987
13988
13989
13990
13991
13992
13993
13994
13995
13996
13997
13998
13999
14000
14001
14002
14003
14004
14005
14006
14007
14008
14009
14010
14011
14012
14013
14014
14015
14016
14017
14018
14019
14020
14021
14022
14023
14024
14025
14026
14027
14028
14029
14030
14031
14032
14033
14034
14035
14036
14037
14038
14039
14040
14041
14042
14043
14044
14045
14046
14047
14048
14049
14050
14051
14052
14053
14054
14055
14056
14057
14058
14059
14060
14061
14062
14063
14064
14065
14066
14067
14068
14069
14070
14071
14072
14073
14074
14075
14076
14077
14078
14079
14080
14081
14082
14083
14084
14085
14086
14087
14088
14089
14090
14091
14092
14093
14094
14095
14096
14097
14098
14099
14100
14101
14102
14103
14104
14105
14106
14107
14108
14109
14110
14111
14112
14113
14114
14115
14116
14117
14118
14119
14120
14121
14122
14123
14124
14125
14126
14127
14128
14129
14130
14131
14132
14133
14134
14135
14136
14137
14138
14139
14140
14141
14142
14143
14144
14145
14146
14147
14148
14149
14150
14151
14152
14153
14154
14155
14156
14157
14158
14159
14160
14161
14162
14163
14164
14165
14166
14167
14168
14169
14170
14171
14172
14173
14174
14175
14176
14177
14178
14179
14180
14181
14182
14183
14184
14185
14186
14187
14188
14189
14190
14191
14192
14193
14194
14195
14196
14197
14198
14199
14200
14201
14202
14203
14204
14205
14206
14207
14208
14209
14210
14211
14212
14213
14214
14215
14216
14217
14218
14219
14220
14221
14222
14223
14224
14225
14226
14227
14228
14229
14230
14231
14232
14233
14234
14235
14236
14237
14238
14239
14240
14241
14242
14243
14244
14245
14246
14247
14248
14249
14250
14251
14252
14253
14254
14255
14256
14257
14258
14259
14260
14261
14262
14263
14264
14265
14266
14267
14268
14269
14270
14271
14272
14273
14274
14275
14276
14277
14278
14279
14280
14281
14282
14283
14284
14285
14286
14287
14288
14289
14290
14291
14292
14293
14294
14295
14296
14297
14298
14299
14300
14301
14302
14303
14304
14305
14306
14307
14308
14309
14310
14311
14312
14313
14314
14315
14316
14317
14318
14319
14320
14321
14322
14323
14324
14325
14326
14327
14328
14329
14330
14331
14332
14333
14334
14335
14336
14337
14338
14339
14340
14341
14342
14343
14344
14345
14346
14347
14348
14349
14350
14351
14352
14353
14354
14355
14356
14357
14358
14359
14360
14361
14362
14363
14364
14365
14366
14367
14368
14369
14370
14371
14372
14373
14374
14375
14376
14377
14378
14379
14380
14381
14382
14383
14384
14385
14386
14387
14388
14389
14390
14391
14392
14393
14394
14395
14396
14397
14398
14399
14400
14401
14402
14403
14404
14405
14406
14407
14408
14409
14410
14411
14412
14413
14414
14415
14416
14417
14418
14419
14420
14421
14422
14423
14424
14425
14426
14427
14428
14429
14430
14431
14432
14433
14434
14435
14436
14437
14438
14439
14440
14441
14442
14443
14444
14445
14446
14447
14448
14449
14450
14451
14452
14453
14454
14455
14456
14457
14458
14459
14460
14461
14462
14463
14464
14465
14466
14467
14468
14469
14470
14471
14472
14473
14474
14475
14476
14477
14478
14479
14480
14481
14482
14483
14484
14485
14486
14487
14488
14489
14490
14491
14492
14493
14494
14495
14496
14497
14498
14499
14500
14501
14502
14503
14504
14505
14506
14507
14508
14509
14510
14511
14512
14513
14514
14515
14516
14517
14518
14519
14520
14521
14522
14523
14524
14525
14526
14527
14528
14529
14530
14531
14532
14533
14534
14535
14536
14537
14538
14539
14540
14541
14542
14543
14544
14545
14546
14547
14548
14549
14550
14551
14552
14553
14554
14555
14556
14557
14558
14559
14560
14561
14562
14563
14564
14565
14566
14567
14568
14569
14570
14571
14572
14573
14574
14575
14576
14577
14578
14579
14580
14581
14582
14583
14584
14585
14586
14587
14588
14589
14590
14591
14592
14593
14594
14595
14596
14597
14598
14599
14600
14601
14602
14603
14604
14605
14606
14607
14608
14609
14610
14611
14612
14613
14614
14615
14616
14617
14618
14619
14620
14621
14622
14623
14624
14625
14626
14627
14628
14629
14630
14631
14632
14633
14634
14635
14636
14637
14638
14639
14640
14641
14642
14643
14644
14645
14646
14647
14648
14649
14650
14651
14652
14653
14654
14655
14656
14657
14658
14659
14660
14661
14662
14663
14664
14665
14666
14667
14668
14669
14670
14671
14672
14673
14674
14675
14676
14677
14678
14679
14680
14681
14682
14683
14684
14685
14686
14687
14688
14689
14690
14691
14692
14693
14694
14695
14696
14697
14698
14699
14700
14701
14702
14703
14704
14705
14706
14707
14708
14709
14710
14711
14712
14713
14714
14715
14716
14717
14718
14719
14720
14721
14722
14723
14724
14725
14726
14727
14728
14729
14730
14731
14732
14733
14734
14735
14736
14737
14738
14739
14740
14741
14742
14743
14744
14745
14746
14747
14748
14749
14750
14751
14752
14753
14754
14755
14756
14757
14758
14759
14760
14761
14762
14763
14764
14765
14766
14767
14768
14769
14770
14771
14772
14773
14774
14775
14776
14777
14778
14779
14780
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
14791
14792
14793
14794
14795
14796
14797
14798
14799
14800
14801
14802
14803
14804
14805
14806
14807
14808
14809
14810
14811
14812
14813
14814
14815
14816
14817
14818
14819
14820
14821
14822
14823
14824
14825
14826
14827
14828
14829
14830
14831
14832
14833
14834
14835
14836
14837
14838
14839
14840
14841
14842
14843
14844
14845
14846
14847
14848
14849
14850
14851
14852
14853
14854
14855
14856
14857
14858
14859
14860
14861
14862
14863
14864
14865
14866
14867
14868
14869
14870
14871
14872
14873
14874
14875
14876
14877
14878
14879
14880
14881
14882
14883
14884
14885
14886
14887
14888
14889
14890
14891
14892
14893
14894
14895
14896
14897
14898
14899
14900
14901
14902
14903
14904
14905
14906
14907
14908
14909
14910
14911
14912
14913
14914
14915
14916
14917
14918
14919
14920
14921
14922
14923
14924
14925
14926
14927
14928
14929
14930
14931
14932
14933
14934
14935
14936
14937
14938
14939
14940
14941
14942
14943
14944
14945
14946
14947
14948
14949
14950
14951
14952
14953
14954
14955
14956
14957
14958
14959
14960
14961
14962
14963
14964
14965
14966
14967
14968
14969
14970
14971
14972
14973
14974
14975
14976
14977
14978
14979
14980
14981
14982
14983
14984
14985
14986
14987
14988
14989
14990
14991
14992
14993
14994
14995
14996
14997
14998
14999
15000
15001
15002
15003
15004
15005
15006
15007
15008
15009
15010
15011
15012
15013
15014
15015
15016
15017
15018
15019
15020
15021
15022
15023
15024
15025
15026
15027
15028
15029
15030
15031
15032
15033
15034
15035
15036
15037
15038
15039
15040
15041
15042
15043
15044
15045
15046
15047
15048
15049
15050
15051
15052
15053
15054
15055
15056
15057
15058
15059
15060
15061
15062
15063
15064
15065
15066
15067
15068
15069
15070
15071
15072
15073
15074
15075
15076
15077
15078
15079
15080
15081
15082
15083
15084
15085
15086
15087
15088
15089
15090
15091
15092
15093
15094
15095
15096
15097
15098
15099
15100
15101
15102
15103
15104
15105
15106
15107
15108
15109
15110
15111
15112
15113
15114
15115
15116
15117
15118
15119
15120
15121
15122
15123
15124
15125
15126
15127
15128
15129
15130
15131
15132
15133
15134
15135
15136
15137
15138
15139
15140
15141
15142
15143
15144
15145
15146
15147
15148
15149
15150
15151
15152
15153
15154
15155
15156
15157
15158
15159
15160
15161
15162
15163
15164
15165
15166
15167
15168
15169
15170
15171
15172
15173
15174
15175
15176
15177
15178
15179
15180
15181
15182
15183
15184
15185
15186
15187
15188
15189
15190
15191
15192
15193
15194
15195
15196
15197
15198
15199
15200
15201
15202
15203
15204
15205
15206
15207
15208
15209
15210
15211
15212
15213
15214
15215
15216
15217
15218
15219
15220
15221
15222
15223
15224
15225
15226
15227
15228
15229
15230
15231
15232
15233
15234
15235
15236
15237
15238
15239
15240
15241
15242
15243
15244
15245
15246
15247
15248
15249
15250
15251
15252
15253
15254
15255
15256
15257
15258
15259
15260
15261
15262
15263
15264
15265
15266
15267
15268
15269
15270
15271
15272
15273
15274
15275
15276
15277
15278
15279
15280
15281
15282
15283
15284
15285
15286
15287
15288
15289
15290
15291
15292
15293
15294
15295
15296
15297
15298
15299
15300
15301
15302
15303
15304
15305
15306
15307
15308
15309
15310
15311
15312
15313
15314
15315
15316
15317
15318
15319
15320
15321
15322
15323
15324
15325
15326
15327
15328
15329
15330
15331
15332
15333
15334
15335
15336
15337
15338
15339
15340
15341
15342
15343
15344
15345
15346
15347
15348
15349
15350
15351
15352
15353
15354
15355
15356
15357
15358
15359
15360
15361
15362
15363
15364
15365
15366
15367
15368
15369
15370
15371
15372
15373
15374
15375
15376
15377
15378
15379
15380
15381
15382
15383
15384
15385
15386
15387
15388
15389
15390
15391
15392
15393
15394
15395
15396
15397
15398
15399
15400
15401
15402
15403
15404
15405
15406
15407
15408
15409
15410
15411
15412
15413
15414
15415
15416
15417
15418
15419
15420
15421
15422
15423
15424
15425
15426
15427
15428
15429
15430
15431
15432
15433
15434
15435
15436
15437
15438
15439
15440
15441
15442
15443
15444
15445
15446
15447
15448
15449
15450
15451
15452
15453
15454
15455
15456
15457
15458
15459
15460
15461
15462
15463
15464
15465
15466
15467
15468
15469
15470
15471
15472
15473
15474
15475
15476
15477
15478
15479
15480
15481
15482
15483
15484
15485
15486
15487
15488
15489
15490
15491
15492
15493
15494
15495
15496
15497
15498
15499
15500
15501
15502
15503
15504
15505
15506
15507
15508
15509
15510
15511
15512
15513
15514
15515
15516
15517
15518
15519
15520
15521
15522
15523
15524
15525
15526
15527
15528
15529
15530
15531
15532
15533
15534
15535
15536
15537
15538
15539
15540
15541
15542
15543
15544
15545
15546
15547
15548
15549
15550
15551
15552
15553
15554
15555
15556
15557
15558
15559
15560
15561
15562
15563
15564
15565
15566
15567
15568
15569
15570
15571
15572
15573
15574
15575
15576
15577
15578
15579
15580
15581
15582
15583
15584
15585
15586
15587
15588
15589
15590
15591
15592
15593
15594
15595
15596
15597
15598
15599
15600
15601
15602
15603
15604
15605
15606
15607
15608
15609
15610
15611
15612
15613
15614
15615
15616
15617
15618
15619
15620
15621
15622
15623
15624
15625
15626
15627
15628
15629
15630
15631
15632
15633
15634
15635
15636
15637
15638
15639
15640
15641
15642
15643
15644
15645
15646
15647
15648
15649
15650
15651
15652
15653
15654
15655
15656
15657
15658
15659
15660
15661
15662
15663
15664
15665
15666
15667
15668
15669
15670
15671
15672
15673
15674
15675
15676
15677
15678
15679
15680
15681
15682
15683
15684
15685
15686
15687
15688
15689
15690
15691
15692
15693
15694
15695
15696
15697
15698
15699
15700
15701
15702
15703
15704
15705
15706
15707
15708
15709
15710
15711
15712
15713
15714
15715
15716
15717
15718
15719
15720
15721
15722
15723
15724
15725
15726
15727
15728
15729
15730
15731
15732
15733
15734
15735
15736
15737
15738
15739
15740
15741
15742
15743
15744
15745
15746
15747
15748
15749
15750
15751
15752
15753
15754
15755
15756
15757
15758
15759
15760
15761
15762
15763
15764
15765
15766
15767
15768
15769
15770
15771
15772
15773
15774
15775
15776
15777
15778
15779
15780
15781
15782
15783
15784
15785
15786
15787
15788
15789
15790
15791
15792
15793
15794
15795
15796
15797
15798
15799
15800
15801
15802
15803
15804
15805
15806
15807
15808
15809
15810
15811
15812
15813
15814
15815
15816
15817
15818
15819
15820
15821
15822
15823
15824
15825
15826
15827
15828
15829
15830
15831
15832
15833
15834
15835
15836
15837
15838
15839
15840
15841
15842
15843
15844
15845
15846
15847
15848
15849
15850
15851
15852
15853
15854
15855
15856
15857
15858
15859
15860
15861
15862
15863
15864
15865
15866
15867
15868
15869
15870
15871
15872
15873
15874
15875
15876
15877
15878
15879
15880
15881
15882
15883
15884
15885
15886
15887
15888
15889
15890
15891
15892
15893
15894
15895
15896
15897
15898
15899
15900
15901
15902
15903
15904
15905
15906
15907
15908
15909
15910
15911
15912
15913
15914
15915
15916
15917
15918
15919
15920
15921
15922
15923
15924
15925
15926
15927
15928
15929
15930
15931
15932
15933
15934
15935
15936
15937
15938
15939
15940
15941
15942
15943
15944
15945
15946
15947
15948
15949
15950
15951
15952
15953
15954
15955
15956
15957
15958
15959
15960
15961
15962
15963
15964
15965
15966
15967
15968
15969
15970
15971
15972
15973
15974
15975
15976
15977
15978
15979
15980
15981
15982
15983
15984
15985
15986
15987
15988
15989
15990
15991
15992
15993
15994
15995
15996
15997
15998
15999
16000
16001
16002
16003
16004
16005
16006
16007
16008
16009
16010
16011
16012
16013
16014
16015
16016
16017
16018
16019
16020
16021
16022
16023
16024
16025
16026
16027
16028
16029
16030
16031
16032
16033
16034
16035
16036
16037
16038
16039
16040
16041
16042
16043
16044
16045
16046
16047
16048
16049
16050
16051
16052
16053
16054
16055
16056
16057
16058
16059
16060
16061
16062
16063
16064
16065
16066
16067
16068
16069
16070
16071
16072
16073
16074
16075
16076
16077
16078
16079
16080
16081
16082
16083
16084
16085
16086
16087
16088
16089
16090
16091
16092
16093
16094
16095
16096
16097
16098
16099
16100
16101
16102
16103
16104
16105
16106
16107
16108
16109
16110
16111
16112
16113
16114
16115
16116
16117
16118
16119
16120
16121
16122
16123
16124
16125
16126
16127
16128
16129
16130
16131
16132
16133
16134
16135
16136
16137
16138
16139
16140
16141
16142
16143
16144
16145
16146
16147
16148
16149
16150
16151
16152
16153
16154
16155
16156
16157
16158
16159
16160
16161
16162
16163
16164
16165
16166
16167
16168
16169
16170
16171
16172
16173
16174
16175
16176
16177
16178
16179
16180
16181
16182
16183
16184
16185
16186
16187
16188
16189
16190
16191
16192
16193
16194
16195
16196
16197
16198
16199
16200
16201
16202
16203
16204
16205
16206
16207
16208
16209
16210
16211
16212
16213
16214
16215
16216
16217
16218
16219
16220
16221
16222
16223
16224
16225
16226
16227
16228
16229
16230
16231
16232
16233
16234
16235
16236
16237
16238
16239
16240
16241
16242
16243
16244
16245
16246
16247
16248
16249
16250
16251
16252
16253
16254
16255
16256
16257
16258
16259
16260
16261
16262
16263
16264
16265
16266
16267
16268
16269
16270
16271
16272
16273
16274
16275
16276
16277
16278
16279
16280
16281
16282
16283
16284
16285
16286
16287
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
16313
16314
16315
16316
16317
16318
16319
16320
16321
16322
16323
16324
16325
16326
16327
16328
16329
16330
16331
16332
16333
16334
16335
16336
16337
16338
16339
16340
16341
16342
16343
16344
16345
16346
16347
16348
16349
16350
16351
16352
16353
16354
16355
16356
16357
16358
16359
16360
16361
16362
16363
16364
16365
16366
16367
16368
16369
16370
16371
16372
16373
16374
16375
16376
16377
16378
16379
16380
16381
16382
16383
16384
16385
16386
16387
16388
16389
16390
16391
16392
16393
16394
16395
16396
16397
16398
16399
16400
16401
16402
16403
16404
16405
16406
16407
16408
16409
16410
16411
16412
16413
16414
16415
16416
16417
16418
16419
16420
16421
16422
16423
16424
16425
16426
16427
16428
16429
16430
16431
16432
16433
16434
16435
16436
16437
16438
16439
16440
16441
16442
16443
16444
16445
16446
16447
16448
16449
16450
16451
16452
16453
16454
16455
16456
16457
16458
16459
16460
16461
16462
16463
16464
16465
16466
16467
16468
16469
16470
16471
16472
16473
16474
16475
16476
16477
16478
16479
16480
16481
16482
16483
16484
16485
16486
16487
16488
16489
16490
16491
16492
16493
16494
16495
16496
16497
16498
16499
16500
16501
16502
16503
16504
16505
16506
16507
16508
16509
16510
16511
16512
16513
16514
16515
16516
16517
16518
16519
16520
16521
16522
16523
16524
16525
16526
16527
16528
16529
16530
16531
16532
16533
16534
16535
16536
16537
16538
16539
16540
16541
16542
16543
16544
16545
16546
16547
16548
16549
16550
16551
16552
16553
16554
16555
16556
16557
16558
16559
16560
16561
16562
16563
16564
16565
16566
16567
16568
16569
16570
16571
16572
16573
16574
16575
16576
16577
16578
16579
16580
16581
16582
16583
16584
16585
16586
16587
16588
16589
16590
16591
16592
16593
16594
16595
16596
16597
16598
16599
16600
16601
16602
16603
16604
16605
16606
16607
16608
16609
16610
16611
16612
16613
16614
16615
16616
16617
16618
16619
16620
16621
16622
16623
16624
16625
16626
16627
16628
16629
16630
16631
16632
16633
16634
16635
16636
16637
16638
16639
16640
16641
16642
16643
16644
16645
16646
16647
16648
16649
16650
16651
16652
16653
16654
16655
16656
16657
16658
16659
16660
16661
16662
16663
16664
16665
16666
16667
16668
16669
16670
16671
16672
16673
16674
16675
16676
16677
16678
16679
16680
16681
16682
16683
16684
16685
16686
16687
16688
16689
16690
16691
16692
16693
16694
16695
16696
16697
16698
16699
16700
16701
16702
16703
16704
16705
16706
16707
16708
16709
16710
16711
16712
16713
16714
16715
16716
16717
16718
16719
16720
16721
16722
16723
16724
16725
16726
16727
16728
16729
16730
16731
16732
16733
16734
16735
16736
16737
16738
16739
16740
16741
16742
16743
16744
16745
16746
16747
16748
16749
16750
16751
16752
16753
16754
16755
16756
16757
16758
16759
16760
16761
16762
16763
16764
16765
16766
16767
16768
16769
16770
16771
16772
16773
16774
16775
16776
16777
16778
16779
16780
16781
16782
16783
16784
16785
16786
16787
16788
16789
16790
16791
16792
16793
16794
16795
16796
16797
16798
16799
16800
16801
16802
16803
16804
16805
16806
16807
16808
16809
16810
16811
16812
16813
16814
16815
16816
16817
16818
16819
16820
16821
16822
16823
16824
16825
16826
16827
16828
16829
16830
16831
16832
16833
16834
16835
16836
16837
16838
16839
16840
16841
16842
16843
16844
16845
16846
16847
16848
16849
16850
16851
16852
16853
16854
16855
16856
16857
16858
16859
16860
16861
16862
16863
16864
16865
16866
16867
16868
16869
16870
16871
16872
16873
16874
16875
16876
16877
16878
16879
16880
16881
16882
16883
16884
16885
16886
16887
16888
16889
16890
16891
16892
16893
16894
16895
16896
16897
16898
16899
16900
16901
16902
16903
16904
16905
16906
16907
16908
16909
16910
16911
16912
16913
16914
16915
16916
16917
16918
16919
16920
16921
16922
16923
16924
16925
16926
16927
16928
16929
16930
16931
16932
16933
16934
16935
16936
16937
16938
16939
16940
16941
16942
16943
16944
16945
16946
16947
16948
16949
16950
16951
16952
16953
16954
16955
16956
16957
16958
16959
16960
16961
16962
16963
16964
16965
16966
16967
16968
16969
16970
16971
16972
16973
16974
16975
16976
16977
16978
16979
16980
16981
16982
16983
16984
16985
16986
16987
16988
16989
16990
16991
16992
16993
16994
16995
16996
16997
16998
16999
17000
17001
17002
17003
17004
17005
17006
17007
17008
17009
17010
17011
17012
17013
17014
17015
17016
17017
17018
17019
17020
17021
17022
17023
17024
17025
17026
17027
17028
17029
17030
17031
17032
17033
17034
17035
17036
17037
17038
17039
17040
17041
17042
17043
17044
17045
17046
17047
17048
17049
17050
17051
17052
17053
17054
17055
17056
17057
17058
17059
17060
17061
17062
17063
17064
17065
17066
17067
17068
17069
17070
17071
17072
17073
17074
17075
17076
17077
17078
17079
17080
17081
17082
17083
17084
17085
17086
17087
17088
17089
17090
17091
17092
17093
17094
17095
17096
17097
17098
17099
17100
17101
17102
17103
17104
17105
17106
17107
17108
17109
17110
17111
17112
17113
17114
17115
17116
17117
17118
17119
17120
17121
17122
17123
17124
17125
17126
17127
17128
17129
17130
17131
17132
17133
17134
17135
17136
17137
17138
17139
17140
17141
17142
17143
17144
17145
17146
17147
17148
17149
17150
17151
17152
17153
17154
17155
17156
17157
17158
17159
17160
17161
17162
17163
17164
17165
17166
17167
17168
17169
17170
17171
17172
17173
17174
17175
17176
17177
17178
17179
17180
17181
17182
17183
17184
17185
17186
17187
17188
17189
17190
17191
17192
17193
17194
17195
17196
17197
17198
17199
17200
17201
17202
17203
17204
17205
17206
17207
17208
17209
17210
17211
17212
17213
17214
17215
17216
17217
17218
17219
17220
17221
17222
17223
17224
17225
17226
17227
17228
17229
17230
17231
17232
17233
17234
17235
17236
17237
17238
17239
17240
17241
17242
17243
17244
17245
17246
17247
17248
17249
17250
17251
17252
17253
17254
17255
17256
17257
17258
17259
17260
17261
17262
17263
17264
17265
17266
17267
17268
17269
17270
17271
17272
17273
17274
17275
17276
17277
17278
17279
17280
17281
17282
17283
17284
17285
17286
17287
17288
17289
17290
17291
17292
17293
17294
17295
17296
17297
17298
17299
17300
17301
17302
17303
17304
17305
17306
17307
17308
17309
17310
17311
17312
17313
17314
17315
17316
17317
17318
17319
17320
17321
17322
17323
17324
17325
17326
17327
17328
17329
17330
17331
17332
17333
17334
17335
17336
17337
17338
17339
17340
17341
17342
17343
17344
17345
17346
17347
17348
17349
17350
17351
17352
17353
17354
17355
17356
17357
17358
17359
17360
17361
17362
17363
17364
17365
17366
17367
17368
17369
17370
17371
17372
17373
17374
17375
17376
17377
17378
17379
17380
17381
17382
17383
17384
17385
17386
17387
17388
17389
17390
17391
17392
17393
17394
17395
17396
17397
17398
17399
17400
17401
17402
17403
17404
17405
17406
17407
17408
17409
17410
17411
17412
17413
17414
17415
17416
17417
17418
17419
17420
17421
17422
17423
17424
17425
17426
17427
17428
17429
17430
17431
17432
17433
17434
17435
17436
17437
17438
17439
17440
17441
17442
17443
17444
17445
17446
17447
17448
17449
17450
17451
17452
17453
17454
17455
17456
17457
17458
17459
17460
17461
17462
17463
17464
17465
17466
17467
17468
17469
17470
17471
17472
17473
17474
17475
17476
17477
17478
17479
17480
17481
17482
17483
17484
17485
17486
17487
17488
17489
17490
17491
17492
17493
17494
17495
17496
17497
17498
17499
17500
17501
17502
17503
17504
17505
17506
17507
17508
17509
17510
17511
17512
17513
17514
17515
17516
17517
17518
17519
17520
17521
17522
17523
17524
17525
17526
17527
17528
17529
17530
17531
17532
17533
17534
17535
17536
17537
17538
17539
17540
17541
17542
17543
17544
17545
17546
17547
17548
17549
17550
17551
17552
17553
17554
17555
17556
17557
17558
17559
17560
17561
17562
17563
17564
17565
17566
17567
17568
17569
17570
17571
17572
17573
17574
17575
17576
17577
17578
17579
17580
17581
17582
17583
17584
17585
17586
17587
17588
17589
17590
17591
17592
17593
17594
17595
17596
17597
17598
17599
17600
17601
17602
17603
17604
17605
17606
17607
17608
17609
17610
17611
17612
17613
17614
17615
17616
17617
17618
17619
17620
17621
17622
17623
17624
17625
17626
17627
17628
17629
17630
17631
17632
17633
17634
17635
17636
17637
17638
17639
17640
17641
17642
17643
17644
17645
17646
17647
17648
17649
17650
17651
17652
17653
17654
17655
17656
17657
17658
17659
17660
17661
17662
17663
17664
17665
17666
17667
17668
17669
17670
17671
17672
17673
17674
17675
17676
17677
17678
17679
17680
17681
17682
17683
17684
17685
17686
17687
17688
17689
17690
17691
17692
17693
17694
17695
17696
17697
17698
17699
17700
17701
17702
17703
17704
17705
17706
17707
17708
17709
17710
17711
17712
17713
17714
17715
17716
17717
17718
17719
17720
17721
17722
17723
17724
17725
17726
17727
17728
17729
17730
17731
17732
17733
17734
17735
17736
17737
17738
17739
17740
17741
17742
17743
17744
17745
17746
17747
17748
17749
17750
17751
17752
17753
17754
17755
17756
17757
17758
17759
17760
17761
17762
17763
17764
17765
17766
17767
17768
17769
17770
17771
17772
17773
17774
17775
17776
17777
17778
17779
17780
17781
17782
17783
17784
17785
17786
17787
17788
17789
17790
17791
17792
17793
17794
17795
17796
17797
17798
17799
17800
17801
17802
17803
17804
17805
17806
17807
17808
17809
17810
17811
17812
17813
17814
17815
17816
17817
17818
17819
17820
17821
17822
17823
17824
17825
17826
17827
17828
17829
17830
17831
17832
17833
17834
17835
17836
17837
17838
17839
17840
17841
17842
17843
17844
17845
17846
17847
17848
17849
17850
17851
17852
17853
17854
17855
17856
17857
17858
17859
17860
17861
17862
17863
17864
17865
17866
17867
17868
17869
17870
17871
17872
17873
17874
17875
17876
17877
17878
17879
17880
17881
17882
17883
17884
17885
17886
17887
17888
17889
17890
17891
17892
17893
17894
17895
17896
17897
17898
17899
17900
17901
17902
17903
17904
17905
17906
17907
17908
17909
17910
17911
17912
17913
17914
17915
17916
17917
17918
17919
17920
17921
17922
17923
17924
17925
17926
17927
17928
17929
17930
17931
17932
17933
17934
17935
17936
17937
17938
17939
17940
17941
17942
17943
17944
17945
17946
17947
17948
17949
17950
17951
17952
17953
17954
17955
17956
17957
17958
17959
17960
17961
17962
17963
17964
17965
17966
17967
17968
17969
17970
17971
17972
17973
17974
17975
17976
17977
17978
17979
17980
17981
17982
17983
17984
17985
17986
17987
17988
17989
17990
17991
17992
17993
17994
17995
17996
17997
17998
17999
18000
18001
18002
18003
18004
18005
18006
18007
18008
18009
18010
18011
18012
18013
18014
18015
18016
18017
18018
18019
18020
18021
18022
18023
18024
18025
18026
18027
18028
18029
18030
18031
18032
18033
18034
18035
18036
18037
18038
18039
18040
18041
18042
18043
18044
18045
18046
18047
18048
18049
18050
18051
18052
18053
18054
18055
18056
18057
18058
18059
18060
18061
18062
18063
18064
18065
18066
18067
18068
18069
18070
18071
18072
18073
18074
18075
18076
18077
18078
18079
18080
18081
18082
18083
18084
18085
18086
18087
18088
18089
18090
18091
18092
18093
18094
18095
18096
18097
18098
18099
18100
18101
18102
18103
18104
18105
18106
18107
18108
18109
18110
18111
18112
18113
18114
18115
18116
18117
18118
18119
18120
18121
18122
18123
18124
18125
18126
18127
18128
18129
18130
18131
18132
18133
18134
18135
18136
18137
18138
18139
18140
18141
18142
18143
18144
18145
18146
18147
18148
18149
18150
18151
18152
18153
18154
18155
18156
18157
18158
18159
18160
18161
18162
18163
18164
18165
18166
18167
18168
18169
18170
18171
18172
18173
18174
18175
18176
18177
18178
18179
18180
18181
18182
18183
18184
18185
18186
18187
18188
18189
18190
18191
18192
18193
18194
18195
18196
18197
18198
18199
18200
18201
18202
18203
18204
18205
18206
18207
18208
18209
18210
18211
18212
18213
18214
18215
18216
18217
18218
18219
18220
18221
18222
18223
18224
18225
18226
18227
18228
18229
18230
18231
18232
18233
18234
18235
18236
18237
18238
18239
18240
18241
18242
18243
18244
18245
18246
18247
18248
18249
18250
18251
18252
18253
18254
18255
18256
18257
18258
18259
18260
18261
18262
18263
18264
18265
18266
18267
18268
18269
18270
18271
18272
18273
18274
18275
18276
18277
18278
18279
18280
18281
18282
18283
18284
18285
18286
18287
18288
18289
18290
18291
18292
18293
18294
18295
18296
18297
18298
18299
18300
18301
18302
18303
18304
18305
18306
18307
18308
18309
18310
18311
18312
18313
18314
18315
18316
18317
18318
18319
18320
18321
18322
18323
18324
18325
18326
18327
18328
18329
18330
18331
18332
18333
18334
18335
18336
18337
18338
18339
18340
18341
18342
18343
18344
18345
18346
18347
18348
18349
18350
18351
18352
18353
18354
18355
18356
18357
18358
18359
18360
18361
18362
18363
18364
18365
18366
18367
18368
18369
18370
18371
18372
18373
18374
18375
18376
18377
18378
18379
18380
18381
18382
18383
18384
18385
18386
18387
18388
18389
18390
18391
18392
18393
18394
18395
18396
18397
18398
18399
18400
18401
18402
18403
18404
18405
18406
18407
18408
18409
18410
18411
18412
18413
18414
18415
18416
18417
18418
18419
18420
18421
18422
18423
18424
18425
18426
18427
18428
18429
18430
18431
18432
18433
18434
18435
18436
18437
18438
18439
18440
18441
18442
18443
18444
18445
18446
18447
18448
18449
18450
18451
18452
18453
18454
18455
18456
18457
18458
18459
18460
18461
18462
18463
18464
18465
18466
18467
18468
18469
18470
18471
18472
18473
18474
18475
18476
18477
18478
18479
18480
18481
18482
18483
18484
18485
18486
18487
18488
18489
18490
18491
18492
18493
18494
18495
18496
18497
18498
18499
18500
18501
18502
18503
18504
18505
18506
18507
18508
18509
18510
18511
18512
18513
18514
18515
18516
18517
18518
18519
18520
18521
18522
18523
18524
18525
18526
18527
18528
18529
18530
18531
18532
18533
18534
18535
18536
18537
18538
18539
18540
18541
18542
18543
18544
18545
18546
18547
18548
18549
18550
18551
18552
18553
18554
18555
18556
18557
18558
18559
18560
18561
18562
18563
18564
18565
18566
18567
18568
18569
18570
18571
18572
18573
18574
18575
18576
18577
18578
18579
18580
18581
18582
18583
18584
18585
18586
18587
18588
18589
18590
18591
18592
18593
18594
18595
18596
18597
18598
18599
18600
18601
18602
18603
18604
18605
18606
18607
18608
18609
18610
18611
18612
18613
18614
18615
18616
18617
18618
18619
18620
18621
18622
18623
18624
18625
18626
18627
18628
18629
18630
18631
18632
18633
18634
18635
18636
18637
18638
18639
18640
18641
18642
18643
18644
18645
18646
18647
18648
18649
18650
18651
18652
18653
18654
18655
18656
18657
18658
18659
18660
18661
18662
18663
18664
18665
18666
18667
18668
18669
18670
18671
18672
18673
18674
18675
18676
18677
18678
18679
18680
18681
18682
18683
18684
18685
18686
18687
18688
18689
18690
18691
18692
18693
18694
18695
18696
18697
18698
18699
18700
18701
18702
18703
18704
18705
18706
18707
18708
18709
18710
18711
18712
18713
18714
18715
18716
18717
18718
18719
18720
18721
18722
18723
18724
18725
18726
18727
18728
18729
18730
18731
18732
18733
18734
18735
18736
18737
18738
18739
18740
18741
18742
18743
18744
18745
18746
18747
18748
18749
18750
18751
18752
18753
18754
18755
18756
18757
18758
18759
18760
18761
18762
18763
18764
18765
18766
18767
18768
18769
18770
18771
18772
18773
18774
18775
18776
18777
18778
18779
18780
18781
18782
18783
18784
18785
18786
18787
18788
18789
18790
18791
18792
18793
18794
18795
18796
18797
18798
18799
18800
18801
18802
18803
18804
18805
18806
18807
18808
18809
18810
18811
18812
18813
18814
18815
18816
18817
18818
18819
18820
18821
18822
18823
18824
18825
18826
18827
18828
18829
18830
18831
18832
18833
18834
18835
18836
18837
18838
18839
18840
18841
18842
18843
18844
18845
18846
18847
18848
18849
18850
18851
18852
18853
18854
18855
18856
18857
18858
18859
18860
18861
18862
18863
18864
18865
18866
18867
18868
18869
18870
18871
18872
18873
18874
18875
18876
18877
18878
18879
18880
18881
18882
18883
18884
18885
18886
18887
18888
18889
18890
18891
18892
18893
18894
18895
18896
18897
18898
18899
18900
18901
18902
18903
18904
18905
18906
18907
18908
18909
18910
18911
18912
18913
18914
18915
18916
18917
18918
18919
18920
18921
18922
18923
18924
18925
18926
18927
18928
18929
18930
18931
18932
18933
18934
18935
18936
18937
18938
18939
18940
18941
18942
18943
18944
18945
18946
18947
18948
18949
18950
18951
18952
18953
18954
18955
18956
18957
18958
18959
18960
18961
18962
18963
18964
18965
18966
18967
18968
18969
18970
18971
18972
18973
18974
18975
18976
18977
18978
18979
18980
18981
18982
18983
18984
18985
18986
18987
18988
18989
18990
18991
18992
18993
18994
18995
18996
18997
18998
18999
19000
19001
19002
19003
19004
19005
19006
19007
19008
19009
19010
19011
19012
19013
19014
19015
19016
19017
19018
19019
19020
19021
19022
19023
19024
19025
19026
19027
19028
19029
19030
19031
19032
19033
19034
19035
19036
19037
19038
19039
19040
19041
19042
19043
19044
19045
19046
19047
19048
19049
19050
19051
19052
19053
19054
19055
19056
19057
19058
19059
19060
19061
19062
19063
19064
19065
19066
19067
19068
19069
19070
19071
19072
19073
19074
19075
19076
19077
19078
19079
19080
19081
19082
19083
19084
19085
19086
19087
19088
19089
19090
19091
19092
19093
19094
19095
19096
19097
19098
19099
19100
19101
19102
19103
19104
19105
19106
19107
19108
19109
19110
19111
19112
19113
19114
19115
19116
19117
19118
19119
19120
19121
19122
19123
19124
19125
19126
19127
19128
19129
19130
19131
19132
19133
19134
19135
19136
19137
19138
19139
19140
19141
19142
19143
19144
19145
19146
19147
19148
19149
19150
19151
19152
19153
19154
19155
19156
19157
19158
19159
19160
19161
19162
19163
19164
19165
19166
19167
19168
19169
19170
19171
19172
19173
19174
19175
19176
19177
19178
19179
19180
19181
19182
19183
19184
19185
19186
19187
19188
19189
19190
19191
19192
19193
19194
19195
19196
19197
19198
19199
19200
19201
19202
19203
19204
19205
19206
19207
19208
19209
19210
19211
19212
19213
19214
19215
19216
19217
19218
19219
19220
19221
19222
19223
19224
19225
19226
19227
19228
19229
19230
19231
19232
19233
19234
19235
19236
19237
19238
19239
19240
19241
19242
19243
19244
19245
19246
19247
19248
19249
19250
19251
19252
19253
19254
19255
19256
19257
19258
19259
19260
19261
19262
19263
19264
19265
19266
19267
19268
19269
19270
19271
19272
19273
19274
19275
19276
19277
19278
19279
19280
19281
19282
19283
19284
19285
19286
19287
19288
19289
19290
19291
19292
19293
19294
19295
19296
19297
19298
19299
19300
19301
19302
19303
19304
19305
19306
19307
19308
19309
19310
19311
19312
19313
19314
19315
19316
19317
19318
19319
19320
19321
19322
19323
19324
19325
19326
19327
19328
19329
19330
19331
19332
19333
19334
19335
19336
19337
19338
19339
19340
19341
19342
19343
19344
19345
19346
19347
19348
19349
19350
19351
19352
19353
19354
19355
19356
19357
19358
19359
19360
19361
19362
19363
19364
19365
19366
19367
19368
19369
19370
19371
19372
19373
19374
19375
19376
19377
19378
19379
19380
19381
19382
19383
19384
19385
19386
19387
19388
19389
19390
19391
19392
19393
19394
19395
19396
19397
19398
19399
19400
19401
19402
19403
19404
19405
19406
19407
19408
19409
19410
19411
19412
19413
19414
19415
19416
19417
19418
19419
19420
19421
19422
19423
19424
19425
19426
19427
19428
19429
19430
19431
19432
19433
19434
19435
19436
19437
19438
19439
19440
19441
19442
19443
19444
19445
19446
19447
19448
19449
19450
19451
19452
19453
19454
19455
19456
19457
19458
19459
19460
19461
19462
19463
19464
19465
19466
19467
19468
19469
19470
19471
19472
19473
19474
19475
19476
19477
19478
19479
19480
19481
19482
19483
19484
19485
19486
19487
19488
19489
19490
19491
19492
19493
19494
19495
19496
19497
19498
19499
19500
19501
19502
19503
19504
19505
19506
19507
19508
19509
19510
19511
19512
19513
19514
19515
19516
19517
19518
19519
19520
19521
19522
19523
19524
19525
19526
19527
19528
19529
19530
19531
19532
19533
19534
19535
19536
19537
19538
19539
19540
19541
19542
19543
19544
19545
19546
19547
19548
19549
19550
19551
19552
19553
19554
19555
19556
19557
19558
19559
19560
19561
19562
19563
19564
19565
19566
19567
19568
19569
19570
19571
19572
19573
19574
19575
19576
19577
19578
19579
19580
19581
19582
19583
19584
19585
19586
19587
19588
19589
19590
19591
19592
19593
19594
19595
19596
19597
19598
19599
19600
19601
19602
19603
19604
19605
19606
19607
19608
19609
19610
19611
19612
19613
19614
19615
19616
19617
19618
19619
19620
19621
19622
19623
19624
19625
19626
19627
19628
19629
19630
19631
19632
19633
19634
19635
19636
19637
19638
19639
19640
19641
19642
19643
19644
19645
19646
19647
19648
19649
19650
19651
19652
19653
19654
19655
19656
19657
19658
19659
19660
19661
19662
19663
19664
19665
19666
19667
19668
19669
19670
19671
19672
19673
19674
19675
19676
19677
19678
19679
19680
19681
19682
19683
19684
19685
19686
19687
19688
19689
19690
19691
19692
19693
19694
19695
19696
19697
19698
19699
19700
19701
19702
19703
19704
19705
19706
19707
19708
19709
19710
19711
19712
19713
19714
19715
19716
19717
19718
19719
19720
19721
19722
19723
19724
19725
19726
19727
19728
19729
19730
19731
19732
19733
19734
19735
19736
19737
19738
19739
19740
19741
19742
19743
19744
19745
19746
19747
19748
19749
19750
19751
19752
19753
19754
19755
19756
19757
19758
19759
19760
19761
19762
19763
19764
19765
19766
19767
19768
19769
19770
19771
19772
19773
19774
19775
19776
19777
19778
19779
19780
19781
19782
19783
19784
19785
19786
19787
19788
19789
19790
19791
19792
19793
19794
19795
19796
19797
19798
19799
19800
19801
19802
19803
19804
19805
19806
19807
19808
19809
19810
19811
19812
19813
19814
19815
19816
19817
19818
19819
19820
19821
19822
19823
19824
19825
19826
19827
19828
19829
19830
19831
19832
19833
19834
19835
19836
19837
19838
19839
19840
19841
19842
19843
19844
19845
19846
19847
19848
19849
19850
19851
19852
19853
19854
19855
19856
19857
19858
19859
19860
19861
19862
19863
19864
19865
19866
19867
19868
19869
19870
19871
19872
19873
19874
19875
19876
19877
19878
19879
19880
19881
19882
19883
19884
19885
19886
19887
19888
19889
19890
19891
19892
19893
19894
19895
19896
19897
19898
19899
19900
19901
19902
19903
19904
19905
19906
19907
19908
19909
19910
19911
19912
19913
19914
19915
19916
19917
19918
19919
19920
19921
19922
19923
19924
19925
19926
19927
19928
19929
19930
19931
19932
19933
19934
19935
19936
19937
19938
19939
19940
19941
19942
19943
19944
19945
19946
19947
19948
19949
19950
19951
19952
19953
19954
19955
19956
19957
19958
19959
19960
19961
19962
19963
19964
19965
19966
19967
19968
19969
19970
19971
19972
19973
19974
19975
19976
19977
19978
19979
19980
19981
19982
19983
19984
19985
19986
19987
19988
19989
19990
19991
19992
19993
19994
19995
19996
19997
19998
19999
20000
20001
20002
20003
20004
20005
20006
20007
20008
20009
20010
20011
20012
20013
20014
20015
20016
20017
20018
20019
20020
20021
20022
20023
20024
20025
20026
20027
20028
20029
20030
20031
20032
20033
20034
20035
20036
20037
20038
20039
20040
20041
20042
20043
20044
20045
20046
20047
20048
20049
20050
20051
20052
20053
20054
20055
20056
20057
20058
20059
20060
20061
20062
20063
20064
20065
20066
20067
20068
20069
20070
20071
20072
20073
20074
20075
20076
20077
20078
20079
20080
20081
20082
20083
20084
20085
20086
20087
20088
20089
20090
20091
20092
20093
20094
20095
20096
20097
20098
20099
20100
20101
20102
20103
20104
20105
20106
20107
20108
20109
20110
20111
20112
20113
20114
20115
20116
20117
20118
20119
20120
20121
20122
20123
20124
20125
20126
20127
20128
20129
20130
20131
20132
20133
20134
20135
20136
20137
20138
20139
20140
20141
20142
20143
20144
20145
20146
20147
20148
20149
20150
20151
20152
20153
20154
20155
20156
20157
20158
20159
20160
20161
20162
20163
20164
20165
20166
20167
20168
20169
20170
20171
20172
20173
20174
20175
20176
20177
20178
20179
20180
20181
20182
20183
20184
20185
20186
20187
20188
20189
20190
20191
20192
20193
20194
20195
20196
20197
20198
20199
20200
20201
20202
20203
20204
20205
20206
20207
20208
20209
20210
20211
20212
20213
20214
20215
20216
20217
20218
20219
20220
20221
20222
20223
20224
20225
20226
20227
20228
20229
20230
20231
20232
20233
20234
20235
20236
20237
20238
20239
20240
20241
20242
20243
20244
20245
20246
20247
20248
20249
20250
20251
20252
20253
20254
20255
20256
20257
20258
20259
20260
20261
20262
20263
20264
20265
20266
20267
20268
20269
20270
20271
20272
20273
20274
20275
20276
20277
20278
20279
20280
20281
20282
20283
20284
20285
20286
20287
20288
20289
20290
20291
20292
20293
20294
20295
20296
20297
20298
20299
20300
20301
20302
20303
20304
20305
20306
20307
20308
20309
20310
20311
20312
20313
20314
20315
20316
20317
20318
20319
20320
20321
20322
20323
20324
20325
20326
20327
20328
20329
20330
20331
20332
20333
20334
20335
20336
20337
20338
20339
20340
20341
20342
20343
20344
20345
20346
20347
20348
20349
20350
20351
20352
20353
20354
20355
20356
20357
20358
20359
20360
20361
20362
20363
20364
20365
20366
20367
20368
20369
20370
20371
20372
20373
20374
20375
20376
20377
20378
20379
20380
20381
20382
20383
20384
20385
20386
20387
20388
20389
20390
20391
20392
20393
20394
20395
20396
20397
20398
20399
20400
20401
20402
20403
20404
20405
20406
20407
20408
20409
20410
20411
20412
20413
20414
20415
20416
20417
20418
20419
20420
20421
20422
20423
20424
20425
20426
20427
20428
20429
20430
20431
20432
20433
20434
20435
20436
20437
20438
20439
20440
20441
20442
20443
20444
20445
20446
20447
20448
20449
20450
20451
20452
20453
20454
20455
20456
20457
20458
20459
20460
20461
20462
20463
20464
20465
20466
20467
20468
20469
20470
20471
20472
20473
20474
20475
20476
20477
20478
20479
20480
20481
20482
20483
20484
20485
20486
20487
20488
20489
20490
20491
20492
20493
20494
20495
20496
20497
20498
20499
20500
20501
20502
20503
20504
20505
20506
20507
20508
20509
20510
20511
20512
20513
20514
20515
20516
20517
20518
20519
20520
20521
20522
20523
20524
20525
20526
20527
20528
20529
20530
20531
20532
20533
20534
20535
20536
20537
20538
20539
20540
20541
20542
20543
20544
20545
20546
20547
20548
20549
20550
20551
20552
20553
20554
20555
20556
20557
20558
20559
20560
20561
20562
20563
20564
20565
20566
20567
20568
20569
20570
20571
20572
20573
20574
20575
20576
20577
20578
20579
20580
20581
20582
20583
20584
20585
20586
20587
20588
20589
20590
20591
20592
20593
20594
20595
20596
20597
20598
20599
20600
20601
20602
20603
20604
20605
20606
20607
20608
20609
20610
20611
20612
20613
20614
20615
20616
20617
20618
20619
20620
20621
20622
20623
20624
20625
20626
20627
20628
20629
20630
20631
20632
20633
20634
20635
20636
20637
20638
20639
20640
20641
20642
20643
20644
20645
20646
20647
20648
20649
20650
20651
20652
20653
20654
20655
20656
20657
20658
20659
20660
20661
20662
20663
20664
20665
20666
20667
20668
20669
20670
20671
20672
20673
20674
20675
20676
20677
20678
20679
20680
20681
20682
20683
20684
20685
20686
20687
20688
20689
20690
20691
20692
20693
20694
20695
20696
20697
20698
20699
20700
20701
20702
20703
20704
20705
20706
20707
20708
20709
20710
20711
20712
20713
20714
20715
20716
20717
20718
20719
20720
20721
20722
20723
20724
20725
20726
20727
20728
20729
20730
20731
20732
20733
20734
20735
20736
20737
20738
20739
20740
20741
20742
20743
20744
20745
20746
20747
20748
20749
20750
20751
20752
20753
20754
20755
20756
20757
20758
20759
20760
20761
20762
20763
20764
20765
20766
20767
20768
20769
20770
20771
20772
20773
20774
20775
20776
20777
20778
20779
20780
20781
20782
20783
20784
20785
20786
20787
20788
20789
20790
20791
20792
20793
20794
20795
20796
20797
20798
20799
20800
20801
20802
20803
20804
20805
20806
20807
20808
20809
20810
20811
20812
20813
20814
20815
20816
20817
20818
20819
20820
20821
20822
20823
20824
20825
20826
20827
20828
20829
20830
20831
20832
20833
20834
20835
20836
20837
20838
20839
20840
20841
20842
20843
20844
20845
20846
20847
20848
20849
20850
20851
20852
20853
20854
20855
20856
20857
20858
20859
20860
20861
20862
20863
20864
20865
20866
20867
20868
20869
20870
20871
20872
20873
20874
20875
20876
20877
20878
20879
20880
20881
20882
20883
20884
20885
20886
20887
20888
20889
20890
20891
20892
20893
20894
20895
20896
20897
20898
20899
20900
20901
20902
20903
20904
20905
20906
20907
20908
20909
20910
20911
20912
20913
20914
20915
20916
20917
20918
20919
20920
20921
20922
20923
20924
20925
20926
20927
20928
20929
20930
20931
20932
20933
20934
20935
20936
20937
20938
20939
20940
20941
20942
20943
20944
20945
20946
20947
20948
20949
20950
20951
20952
20953
20954
20955
20956
20957
20958
20959
20960
20961
20962
20963
20964
20965
20966
20967
20968
20969
20970
20971
20972
20973
20974
20975
20976
20977
20978
20979
20980
20981
20982
20983
20984
20985
20986
20987
20988
20989
20990
20991
20992
20993
20994
20995
20996
20997
20998
20999
21000
21001
21002
21003
21004
21005
21006
21007
21008
21009
21010
21011
21012
21013
21014
21015
21016
21017
21018
21019
21020
21021
21022
21023
21024
21025
21026
21027
21028
21029
21030
21031
21032
21033
21034
21035
21036
21037
21038
21039
21040
21041
21042
21043
21044
21045
21046
21047
21048
21049
21050
21051
21052
21053
21054
21055
21056
21057
21058
21059
21060
21061
21062
21063
21064
21065
21066
21067
21068
21069
21070
21071
21072
21073
21074
21075
21076
21077
21078
21079
21080
21081
21082
21083
21084
21085
21086
21087
21088
21089
21090
21091
21092
21093
21094
21095
21096
21097
21098
21099
21100
21101
21102
21103
21104
21105
21106
21107
21108
21109
21110
21111
21112
21113
21114
21115
21116
21117
21118
21119
21120
21121
21122
21123
21124
21125
21126
21127
21128
21129
21130
21131
21132
21133
21134
21135
21136
21137
21138
21139
21140
21141
21142
21143
21144
21145
21146
21147
21148
21149
21150
21151
21152
21153
21154
21155
21156
21157
21158
21159
21160
21161
21162
21163
21164
21165
21166
21167
21168
21169
21170
21171
21172
21173
21174
21175
21176
21177
21178
21179
21180
21181
21182
21183
21184
21185
21186
21187
21188
21189
21190
21191
21192
21193
21194
21195
21196
21197
21198
21199
21200
21201
21202
21203
21204
21205
21206
21207
21208
21209
21210
21211
21212
21213
21214
21215
21216
21217
21218
21219
21220
21221
21222
21223
21224
21225
21226
21227
21228
21229
21230
21231
21232
21233
21234
21235
21236
21237
21238
21239
21240
21241
21242
21243
21244
21245
21246
21247
21248
21249
21250
21251
21252
21253
21254
21255
21256
21257
21258
21259
21260
21261
21262
21263
21264
21265
21266
21267
21268
21269
21270
21271
21272
21273
21274
21275
21276
21277
21278
21279
21280
21281
21282
21283
21284
21285
21286
21287
21288
21289
21290
21291
21292
21293
21294
21295
21296
21297
21298
21299
21300
21301
21302
21303
21304
21305
21306
21307
21308
21309
21310
21311
21312
21313
21314
21315
21316
21317
21318
21319
21320
21321
21322
21323
21324
21325
21326
21327
21328
21329
21330
21331
21332
21333
21334
21335
21336
21337
21338
21339
21340
21341
21342
21343
21344
21345
21346
21347
21348
21349
21350
21351
21352
21353
21354
21355
21356
21357
21358
21359
21360
21361
21362
21363
21364
21365
21366
21367
21368
21369
21370
21371
21372
21373
21374
21375
21376
21377
21378
21379
21380
21381
21382
21383
21384
21385
21386
21387
21388
21389
21390
21391
21392
21393
21394
21395
21396
21397
21398
21399
21400
21401
21402
21403
21404
21405
21406
21407
21408
21409
21410
21411
21412
21413
21414
21415
21416
21417
21418
21419
21420
21421
21422
21423
21424
21425
21426
21427
21428
21429
21430
21431
21432
21433
21434
21435
21436
21437
21438
21439
21440
21441
21442
21443
21444
21445
21446
21447
21448
21449
21450
21451
21452
21453
21454
21455
21456
21457
21458
21459
21460
21461
21462
21463
21464
21465
21466
21467
21468
21469
21470
21471
21472
21473
21474
21475
21476
21477
21478
21479
21480
21481
21482
21483
21484
21485
21486
21487
21488
21489
21490
21491
21492
21493
21494
21495
21496
21497
21498
21499
21500
21501
21502
21503
21504
21505
21506
21507
21508
21509
21510
21511
21512
21513
21514
21515
21516
21517
21518
21519
21520
21521
21522
21523
21524
21525
21526
21527
21528
21529
21530
21531
21532
21533
21534
21535
21536
21537
21538
21539
21540
21541
21542
21543
21544
21545
21546
21547
21548
21549
21550
21551
21552
21553
21554
21555
21556
21557
21558
21559
21560
21561
21562
21563
21564
21565
21566
21567
21568
21569
21570
21571
21572
21573
21574
21575
21576
21577
21578
21579
21580
21581
21582
21583
21584
21585
21586
21587
21588
21589
21590
21591
21592
21593
21594
21595
21596
21597
21598
21599
21600
21601
21602
21603
21604
21605
21606
21607
21608
21609
21610
21611
21612
21613
21614
21615
21616
21617
21618
21619
21620
21621
21622
21623
21624
21625
21626
21627
21628
21629
21630
21631
21632
21633
21634
21635
21636
21637
21638
21639
21640
21641
21642
21643
21644
21645
21646
21647
21648
21649
21650
21651
21652
21653
21654
21655
21656
21657
21658
21659
21660
21661
21662
21663
21664
21665
21666
21667
21668
21669
21670
21671
21672
21673
21674
21675
21676
21677
21678
21679
21680
21681
21682
21683
21684
21685
21686
21687
21688
21689
21690
21691
21692
21693
21694
21695
21696
21697
21698
21699
21700
21701
21702
21703
21704
21705
21706
21707
21708
21709
21710
21711
21712
21713
21714
21715
21716
21717
21718
21719
21720
21721
21722
21723
21724
21725
21726
21727
21728
21729
21730
21731
21732
21733
21734
21735
21736
21737
21738
21739
21740
21741
21742
21743
21744
21745
21746
21747
21748
21749
21750
21751
21752
21753
21754
21755
21756
21757
21758
21759
21760
21761
21762
21763
21764
21765
21766
21767
21768
21769
21770
21771
21772
21773
21774
21775
21776
21777
21778
21779
21780
21781
21782
21783
21784
21785
21786
21787
21788
21789
21790
21791
21792
21793
21794
21795
21796
21797
21798
21799
21800
21801
21802
21803
21804
21805
21806
21807
21808
21809
21810
21811
21812
21813
21814
21815
21816
21817
21818
21819
21820
21821
21822
21823
21824
21825
21826
21827
21828
21829
21830
21831
21832
21833
21834
21835
21836
21837
21838
21839
21840
21841
21842
21843
21844
21845
21846
21847
21848
21849
21850
21851
21852
21853
21854
21855
21856
21857
21858
21859
21860
21861
21862
21863
21864
21865
21866
21867
21868
21869
21870
21871
21872
21873
21874
21875
21876
21877
21878
21879
21880
21881
21882
21883
21884
21885
21886
21887
21888
21889
21890
21891
21892
21893
21894
21895
21896
21897
21898
21899
21900
21901
21902
21903
21904
21905
21906
21907
21908
21909
21910
21911
21912
21913
21914
21915
21916
21917
21918
21919
21920
21921
21922
21923
21924
21925
21926
21927
21928
21929
21930
21931
21932
21933
21934
21935
21936
21937
21938
21939
21940
21941
21942
21943
21944
21945
21946
21947
21948
21949
21950
21951
21952
21953
21954
21955
21956
21957
21958
21959
21960
21961
21962
21963
21964
21965
21966
21967
21968
21969
21970
21971
21972
21973
21974
21975
21976
21977
21978
21979
21980
21981
21982
21983
21984
21985
21986
21987
21988
21989
21990
21991
21992
21993
21994
21995
21996
21997
21998
21999
22000
22001
22002
22003
22004
22005
22006
22007
22008
22009
22010
22011
22012
22013
22014
22015
22016
22017
22018
22019
22020
22021
22022
22023
22024
22025
22026
22027
22028
22029
22030
22031
22032
22033
22034
22035
22036
22037
22038
22039
22040
22041
22042
22043
22044
22045
22046
22047
22048
22049
22050
22051
22052
22053
22054
22055
22056
22057
22058
22059
22060
22061
22062
22063
22064
22065
22066
22067
22068
22069
22070
22071
22072
22073
22074
22075
22076
22077
22078
22079
22080
22081
22082
22083
22084
22085
22086
22087
22088
22089
22090
22091
22092
22093
22094
22095
22096
22097
22098
22099
22100
22101
22102
22103
22104
22105
22106
22107
22108
22109
22110
22111
22112
22113
22114
22115
22116
22117
22118
22119
22120
22121
22122
22123
22124
22125
22126
22127
22128
22129
22130
22131
22132
22133
22134
22135
22136
22137
22138
22139
22140
22141
22142
22143
22144
22145
22146
22147
22148
22149
22150
22151
22152
22153
22154
22155
22156
22157
22158
22159
22160
22161
22162
22163
22164
22165
22166
22167
22168
22169
22170
22171
22172
22173
22174
22175
22176
22177
22178
22179
22180
22181
22182
22183
22184
22185
22186
22187
22188
22189
22190
22191
22192
22193
22194
22195
22196
22197
22198
22199
22200
22201
22202
22203
22204
22205
22206
22207
22208
22209
22210
22211
22212
22213
22214
22215
22216
22217
22218
22219
22220
22221
22222
22223
22224
22225
22226
22227
22228
22229
22230
22231
22232
22233
22234
22235
22236
22237
22238
22239
22240
22241
22242
22243
22244
22245
22246
22247
22248
22249
22250
22251
22252
22253
22254
22255
22256
22257
22258
22259
22260
22261
22262
22263
22264
22265
22266
22267
22268
22269
22270
22271
22272
22273
22274
22275
22276
22277
22278
22279
22280
22281
22282
22283
22284
22285
22286
22287
22288
22289
22290
22291
22292
22293
22294
22295
22296
22297
22298
22299
22300
22301
22302
22303
22304
22305
22306
22307
22308
22309
22310
22311
22312
22313
22314
22315
22316
22317
22318
22319
22320
22321
22322
22323
22324
22325
22326
22327
22328
22329
22330
22331
22332
22333
22334
22335
22336
22337
22338
22339
22340
22341
22342
22343
22344
22345
22346
22347
22348
22349
22350
22351
22352
22353
22354
22355
22356
22357
22358
22359
22360
22361
22362
22363
22364
22365
22366
22367
22368
22369
22370
22371
22372
22373
22374
22375
22376
22377
22378
22379
22380
22381
22382
22383
22384
22385
22386
22387
22388
22389
22390
22391
22392
22393
22394
22395
22396
22397
22398
22399
22400
22401
22402
22403
22404
22405
22406
22407
22408
22409
22410
22411
22412
22413
22414
22415
22416
22417
22418
22419
22420
22421
22422
22423
22424
22425
22426
22427
22428
22429
22430
22431
22432
22433
22434
22435
22436
22437
22438
22439
22440
22441
22442
22443
22444
22445
22446
22447
22448
22449
22450
22451
22452
22453
22454
22455
22456
22457
22458
22459
22460
22461
22462
22463
22464
22465
22466
22467
22468
22469
22470
22471
22472
22473
22474
22475
22476
22477
22478
22479
22480
22481
22482
22483
22484
22485
22486
22487
22488
22489
22490
22491
22492
22493
22494
22495
22496
22497
22498
22499
22500
22501
22502
22503
22504
22505
22506
22507
22508
22509
22510
22511
22512
22513
22514
22515
22516
22517
22518
22519
22520
22521
22522
22523
22524
22525
22526
22527
22528
22529
22530
22531
22532
22533
22534
22535
22536
22537
22538
22539
22540
22541
22542
22543
22544
22545
22546
22547
22548
22549
22550
22551
22552
22553
22554
22555
22556
22557
22558
22559
22560
22561
22562
22563
22564
22565
22566
22567
22568
22569
22570
22571
22572
22573
22574
22575
22576
22577
22578
22579
22580
22581
22582
22583
22584
22585
22586
22587
22588
22589
22590
22591
22592
22593
22594
22595
22596
22597
22598
22599
22600
22601
22602
22603
22604
22605
22606
22607
22608
22609
22610
22611
22612
22613
22614
22615
22616
22617
22618
22619
22620
22621
22622
22623
22624
22625
22626
22627
22628
22629
22630
22631
22632
22633
22634
22635
22636
22637
22638
22639
22640
22641
22642
22643
22644
22645
22646
22647
22648
22649
22650
22651
22652
22653
22654
22655
22656
22657
22658
22659
22660
22661
22662
22663
22664
22665
22666
22667
22668
22669
22670
22671
22672
22673
22674
22675
22676
22677
22678
22679
22680
22681
22682
22683
22684
22685
22686
22687
22688
22689
22690
22691
22692
22693
22694
22695
22696
22697
22698
22699
22700
22701
22702
22703
22704
22705
22706
22707
22708
22709
22710
22711
22712
22713
22714
22715
22716
22717
22718
22719
22720
22721
22722
22723
22724
22725
22726
22727
22728
22729
22730
22731
22732
22733
22734
22735
22736
22737
22738
22739
22740
22741
22742
22743
22744
22745
22746
22747
22748
22749
22750
22751
22752
22753
22754
22755
22756
22757
22758
22759
22760
22761
22762
22763
22764
22765
22766
22767
22768
22769
22770
22771
22772
22773
22774
22775
22776
22777
22778
22779
22780
22781
22782
22783
22784
22785
22786
22787
22788
22789
22790
22791
22792
22793
22794
22795
22796
22797
22798
22799
22800
22801
22802
22803
22804
22805
22806
22807
22808
22809
22810
22811
22812
22813
22814
22815
22816
22817
22818
22819
22820
22821
22822
22823
22824
22825
22826
22827
22828
22829
22830
22831
22832
22833
22834
22835
22836
22837
22838
22839
22840
22841
22842
22843
22844
22845
22846
22847
22848
22849
22850
22851
22852
22853
22854
22855
22856
22857
22858
22859
22860
22861
22862
22863
22864
22865
22866
22867
22868
22869
22870
22871
22872
22873
22874
22875
22876
22877
22878
22879
22880
22881
22882
22883
22884
22885
22886
22887
22888
22889
22890
22891
22892
22893
22894
22895
22896
22897
22898
22899
22900
22901
22902
22903
22904
22905
22906
22907
22908
22909
22910
22911
22912
22913
22914
22915
22916
22917
22918
22919
22920
22921
22922
22923
22924
22925
22926
22927
22928
22929
22930
22931
22932
22933
22934
22935
22936
22937
22938
22939
22940
22941
22942
22943
22944
22945
22946
22947
22948
22949
22950
22951
22952
22953
22954
22955
22956
22957
22958
22959
22960
22961
22962
22963
22964
22965
22966
22967
22968
22969
22970
22971
22972
22973
22974
22975
22976
22977
22978
22979
22980
22981
22982
22983
22984
22985
22986
22987
22988
22989
22990
22991
22992
22993
22994
22995
22996
22997
22998
22999
23000
23001
23002
23003
23004
23005
23006
23007
23008
23009
23010
23011
23012
23013
23014
23015
23016
23017
23018
23019
23020
23021
23022
23023
23024
23025
23026
23027
23028
23029
23030
23031
23032
23033
23034
23035
23036
23037
23038
23039
23040
23041
23042
23043
23044
23045
23046
23047
23048
23049
23050
23051
23052
23053
23054
23055
23056
23057
23058
23059
23060
23061
23062
23063
23064
23065
23066
23067
23068
23069
23070
23071
23072
23073
23074
23075
23076
23077
23078
23079
23080
23081
23082
23083
23084
23085
23086
23087
23088
23089
23090
23091
23092
23093
23094
23095
23096
23097
23098
23099
23100
23101
23102
23103
23104
23105
23106
23107
23108
23109
23110
23111
23112
23113
23114
23115
23116
23117
23118
23119
23120
23121
23122
23123
23124
23125
23126
23127
23128
23129
23130
23131
23132
23133
23134
23135
23136
23137
23138
23139
23140
23141
23142
23143
23144
23145
23146
23147
23148
23149
23150
23151
23152
23153
23154
23155
23156
23157
23158
23159
23160
23161
23162
23163
23164
23165
23166
23167
23168
23169
23170
23171
23172
23173
23174
23175
23176
23177
23178
23179
23180
23181
23182
23183
23184
23185
23186
23187
23188
23189
23190
23191
23192
23193
23194
23195
23196
23197
23198
23199
23200
23201
23202
23203
23204
23205
23206
23207
23208
23209
23210
23211
23212
23213
23214
23215
23216
23217
23218
23219
23220
23221
23222
23223
23224
23225
23226
23227
23228
23229
23230
23231
23232
23233
23234
23235
23236
23237
23238
23239
23240
23241
23242
23243
23244
23245
23246
23247
23248
23249
23250
23251
23252
23253
23254
23255
23256
23257
23258
23259
23260
23261
23262
23263
23264
23265
23266
23267
23268
23269
23270
23271
23272
23273
23274
23275
23276
23277
23278
23279
23280
23281
23282
23283
23284
23285
23286
23287
23288
23289
23290
23291
23292
23293
23294
23295
23296
23297
23298
23299
23300
23301
23302
23303
23304
23305
23306
23307
23308
23309
23310
23311
23312
23313
23314
23315
23316
23317
23318
23319
23320
23321
23322
23323
23324
23325
23326
23327
23328
23329
23330
23331
23332
23333
23334
23335
23336
23337
23338
23339
23340
23341
23342
23343
23344
23345
23346
23347
23348
23349
23350
23351
23352
23353
23354
23355
23356
23357
23358
23359
23360
23361
23362
23363
23364
23365
23366
23367
23368
23369
23370
23371
23372
23373
23374
23375
23376
23377
23378
23379
23380
23381
23382
23383
23384
23385
23386
23387
23388
23389
23390
23391
23392
23393
23394
23395
23396
23397
23398
23399
23400
23401
23402
23403
23404
23405
23406
23407
23408
23409
23410
23411
23412
23413
23414
23415
23416
23417
23418
23419
23420
23421
23422
23423
23424
23425
23426
23427
23428
23429
23430
23431
23432
23433
23434
23435
23436
23437
23438
23439
23440
23441
23442
23443
23444
23445
23446
23447
23448
23449
23450
23451
23452
23453
23454
23455
23456
23457
23458
23459
23460
23461
23462
23463
23464
23465
23466
23467
23468
23469
23470
23471
23472
23473
23474
23475
23476
23477
23478
23479
23480
23481
23482
23483
23484
23485
23486
23487
23488
23489
23490
23491
23492
23493
23494
23495
23496
23497
23498
23499
23500
23501
23502
23503
23504
23505
23506
23507
23508
23509
23510
23511
23512
23513
23514
23515
23516
23517
23518
23519
23520
23521
23522
23523
23524
23525
23526
23527
23528
23529
23530
23531
23532
23533
23534
23535
23536
23537
23538
23539
23540
23541
23542
23543
23544
23545
23546
23547
23548
23549
23550
23551
23552
23553
23554
23555
23556
23557
23558
23559
23560
23561
23562
23563
23564
23565
23566
23567
23568
23569
23570
23571
23572
23573
23574
23575
23576
23577
23578
23579
23580
23581
23582
23583
23584
23585
23586
23587
23588
23589
23590
23591
23592
23593
23594
23595
23596
23597
23598
23599
23600
23601
23602
23603
23604
23605
23606
23607
23608
23609
23610
23611
23612
23613
23614
23615
23616
23617
23618
23619
23620
23621
23622
23623
23624
23625
23626
23627
23628
23629
23630
23631
23632
23633
23634
23635
23636
23637
23638
23639
23640
23641
23642
23643
23644
23645
23646
23647
23648
23649
23650
23651
23652
23653
23654
23655
23656
23657
23658
23659
23660
23661
23662
23663
23664
23665
23666
23667
23668
23669
23670
23671
23672
23673
23674
23675
23676
23677
23678
23679
23680
23681
23682
23683
23684
23685
23686
23687
23688
23689
23690
23691
23692
23693
23694
23695
23696
23697
23698
23699
23700
23701
23702
23703
23704
23705
23706
23707
23708
23709
23710
23711
23712
23713
23714
23715
23716
23717
23718
23719
23720
23721
23722
23723
23724
23725
23726
23727
23728
23729
23730
23731
23732
23733
23734
23735
23736
23737
23738
23739
23740
23741
23742
23743
23744
23745
23746
23747
23748
23749
23750
23751
23752
23753
23754
23755
23756
23757
23758
23759
23760
23761
23762
23763
23764
23765
23766
23767
23768
23769
23770
23771
23772
23773
23774
23775
23776
23777
23778
23779
23780
23781
23782
23783
23784
23785
23786
23787
23788
23789
23790
23791
23792
23793
23794
23795
23796
23797
23798
23799
23800
23801
23802
23803
23804
23805
23806
23807
23808
23809
23810
23811
23812
23813
23814
23815
23816
23817
23818
23819
23820
23821
23822
23823
23824
23825
23826
23827
23828
23829
23830
23831
23832
23833
23834
23835
23836
23837
23838
23839
23840
23841
23842
23843
23844
23845
23846
23847
23848
23849
23850
23851
23852
23853
23854
23855
23856
23857
23858
23859
23860
23861
23862
23863
23864
23865
23866
23867
23868
23869
23870
23871
23872
23873
23874
23875
23876
23877
23878
23879
23880
23881
23882
23883
23884
23885
23886
23887
23888
23889
23890
23891
23892
23893
23894
23895
23896
23897
23898
23899
23900
23901
23902
23903
23904
23905
23906
23907
23908
23909
23910
23911
23912
23913
23914
23915
23916
23917
23918
23919
23920
23921
23922
23923
23924
23925
23926
23927
23928
23929
23930
23931
23932
23933
23934
23935
23936
23937
23938
23939
23940
23941
23942
23943
23944
23945
23946
23947
23948
23949
23950
23951
23952
23953
23954
23955
23956
23957
23958
23959
23960
23961
23962
23963
23964
23965
23966
23967
23968
23969
23970
23971
23972
23973
23974
23975
23976
23977
23978
23979
23980
23981
23982
23983
23984
23985
23986
23987
23988
23989
23990
23991
23992
23993
23994
23995
23996
23997
23998
23999
24000
24001
24002
24003
24004
24005
24006
24007
24008
24009
24010
24011
24012
24013
24014
24015
24016
24017
24018
24019
24020
24021
24022
24023
24024
24025
24026
24027
24028
24029
24030
24031
24032
24033
24034
24035
24036
24037
24038
24039
24040
24041
24042
24043
24044
24045
24046
24047
24048
24049
24050
24051
24052
24053
24054
24055
24056
24057
24058
24059
24060
24061
24062
24063
24064
24065
24066
24067
24068
24069
24070
24071
24072
24073
24074
24075
24076
24077
24078
24079
24080
24081
24082
24083
24084
24085
24086
24087
24088
24089
24090
24091
24092
24093
24094
24095
24096
24097
24098
24099
24100
24101
24102
24103
24104
24105
24106
24107
24108
24109
24110
24111
24112
24113
24114
24115
24116
24117
24118
24119
24120
24121
24122
24123
24124
24125
24126
24127
24128
24129
24130
24131
24132
24133
24134
24135
24136
24137
24138
24139
24140
24141
24142
24143
24144
24145
24146
24147
24148
24149
24150
24151
24152
24153
24154
24155
24156
24157
24158
24159
24160
24161
24162
24163
24164
24165
24166
24167
24168
24169
24170
24171
24172
24173
24174
24175
24176
24177
24178
24179
24180
24181
24182
24183
24184
24185
24186
24187
24188
24189
24190
24191
24192
24193
24194
24195
24196
24197
24198
24199
24200
24201
24202
24203
24204
24205
24206
24207
24208
24209
24210
24211
24212
24213
24214
24215
24216
24217
24218
24219
24220
24221
24222
24223
24224
24225
24226
24227
24228
24229
24230
24231
24232
24233
24234
24235
24236
24237
24238
24239
24240
24241
24242
24243
24244
24245
24246
24247
24248
24249
24250
24251
24252
24253
24254
24255
24256
24257
24258
24259
24260
24261
24262
24263
24264
24265
24266
24267
24268
24269
24270
24271
24272
24273
24274
24275
24276
24277
24278
24279
24280
24281
24282
24283
24284
24285
24286
24287
24288
24289
24290
24291
24292
24293
24294
24295
24296
24297
24298
24299
24300
24301
24302
24303
24304
24305
24306
24307
24308
24309
24310
24311
24312
24313
24314
24315
24316
24317
24318
24319
24320
24321
24322
24323
24324
24325
24326
24327
24328
24329
24330
24331
24332
24333
24334
24335
24336
24337
24338
24339
24340
24341
24342
24343
24344
24345
24346
24347
24348
24349
24350
24351
24352
24353
24354
24355
24356
24357
24358
24359
24360
24361
24362
24363
24364
24365
24366
24367
24368
24369
24370
24371
24372
24373
24374
24375
24376
24377
24378
24379
24380
24381
24382
24383
24384
24385
24386
24387
24388
24389
24390
24391
24392
24393
24394
24395
24396
24397
24398
24399
24400
24401
24402
24403
24404
24405
24406
24407
24408
24409
24410
24411
24412
24413
24414
24415
24416
24417
24418
24419
24420
24421
24422
24423
24424
24425
24426
24427
24428
24429
24430
24431
24432
24433
24434
24435
24436
24437
24438
24439
24440
24441
24442
24443
24444
24445
24446
24447
24448
24449
24450
24451
24452
24453
24454
24455
24456
24457
24458
24459
24460
24461
24462
24463
24464
24465
24466
24467
24468
24469
24470
24471
24472
24473
24474
24475
24476
24477
24478
24479
24480
24481
24482
24483
24484
24485
24486
24487
24488
24489
24490
24491
24492
24493
24494
24495
24496
24497
24498
24499
24500
24501
24502
24503
24504
24505
24506
24507
24508
24509
24510
24511
24512
24513
24514
24515
24516
24517
24518
24519
24520
24521
24522
24523
24524
24525
24526
24527
24528
24529
24530
24531
24532
24533
24534
24535
24536
24537
24538
24539
24540
24541
24542
24543
24544
24545
24546
24547
24548
24549
24550
24551
24552
24553
24554
24555
24556
24557
24558
24559
24560
24561
24562
24563
24564
24565
24566
24567
24568
24569
24570
24571
24572
24573
24574
24575
24576
24577
24578
24579
24580
24581
24582
24583
24584
24585
24586
24587
24588
24589
24590
24591
24592
24593
24594
24595
24596
24597
24598
24599
24600
24601
24602
24603
24604
24605
24606
24607
24608
24609
24610
24611
24612
24613
24614
24615
24616
24617
24618
24619
24620
24621
24622
24623
24624
24625
24626
24627
24628
24629
24630
24631
24632
24633
24634
24635
24636
24637
24638
24639
24640
24641
24642
24643
24644
24645
24646
24647
24648
24649
24650
24651
24652
24653
24654
24655
24656
24657
24658
24659
24660
24661
24662
24663
24664
24665
24666
24667
24668
24669
24670
24671
24672
24673
24674
24675
24676
24677
24678
24679
24680
24681
24682
24683
24684
24685
24686
24687
24688
24689
24690
24691
24692
24693
24694
24695
24696
24697
24698
24699
24700
24701
24702
24703
24704
24705
24706
24707
24708
24709
24710
24711
24712
24713
24714
24715
24716
24717
24718
24719
24720
24721
24722
24723
24724
24725
24726
24727
24728
24729
24730
24731
24732
24733
24734
24735
24736
24737
24738
24739
24740
24741
24742
24743
24744
24745
24746
24747
24748
24749
24750
24751
24752
24753
24754
24755
24756
24757
24758
24759
24760
24761
24762
24763
24764
24765
24766
24767
24768
24769
24770
24771
24772
24773
24774
24775
24776
24777
24778
24779
24780
24781
24782
24783
24784
24785
24786
24787
24788
24789
24790
24791
24792
24793
24794
24795
24796
24797
24798
24799
24800
24801
24802
24803
24804
24805
24806
24807
24808
24809
24810
24811
24812
24813
24814
24815
24816
24817
24818
24819
24820
24821
24822
24823
24824
24825
24826
24827
24828
24829
24830
24831
24832
24833
24834
24835
24836
24837
24838
24839
24840
24841
24842
24843
24844
24845
24846
24847
24848
24849
24850
24851
24852
24853
24854
24855
24856
24857
24858
24859
24860
24861
24862
24863
24864
24865
24866
24867
24868
24869
24870
24871
24872
24873
24874
24875
24876
24877
24878
24879
24880
24881
24882
24883
24884
24885
24886
24887
24888
24889
24890
24891
24892
24893
24894
24895
24896
24897
24898
24899
24900
24901
24902
24903
24904
24905
24906
24907
24908
24909
24910
24911
24912
24913
24914
24915
24916
24917
24918
24919
24920
24921
24922
24923
24924
24925
24926
24927
24928
24929
24930
24931
24932
24933
24934
24935
24936
24937
24938
24939
24940
24941
24942
24943
24944
24945
24946
24947
24948
24949
24950
24951
24952
24953
24954
24955
24956
24957
24958
24959
24960
24961
24962
24963
24964
24965
24966
24967
24968
24969
24970
24971
24972
24973
24974
24975
24976
24977
24978
24979
24980
24981
24982
24983
24984
24985
24986
24987
24988
24989
24990
24991
24992
24993
24994
24995
24996
24997
24998
24999
25000
25001
25002
25003
25004
25005
25006
25007
25008
25009
25010
25011
25012
25013
25014
25015
25016
25017
25018
25019
25020
25021
25022
25023
25024
25025
25026
25027
25028
25029
25030
25031
25032
25033
25034
25035
25036
25037
25038
25039
25040
25041
25042
25043
25044
25045
25046
25047
25048
25049
25050
25051
25052
25053
25054
25055
25056
25057
25058
25059
25060
25061
25062
25063
25064
25065
25066
25067
25068
25069
25070
25071
25072
25073
25074
25075
25076
25077
25078
25079
25080
25081
25082
25083
25084
25085
25086
25087
25088
25089
25090
25091
25092
25093
25094
25095
25096
25097
25098
25099
25100
25101
25102
25103
25104
25105
25106
25107
25108
25109
25110
25111
25112
25113
25114
25115
25116
25117
25118
25119
25120
25121
25122
25123
25124
25125
25126
25127
25128
25129
25130
25131
25132
25133
25134
25135
25136
25137
25138
25139
25140
25141
25142
25143
25144
25145
25146
25147
25148
25149
25150
25151
25152
25153
25154
25155
25156
25157
25158
25159
25160
25161
25162
25163
25164
25165
25166
25167
25168
25169
25170
25171
25172
25173
25174
25175
25176
25177
25178
25179
25180
25181
25182
25183
25184
25185
25186
25187
25188
25189
25190
25191
25192
25193
25194
25195
25196
25197
25198
25199
25200
25201
25202
25203
25204
25205
25206
25207
25208
25209
25210
25211
25212
25213
25214
25215
25216
25217
25218
25219
25220
25221
25222
25223
25224
25225
25226
25227
25228
25229
25230
25231
25232
25233
25234
25235
25236
25237
25238
25239
25240
25241
25242
25243
25244
25245
25246
25247
25248
25249
25250
25251
25252
25253
25254
25255
25256
25257
25258
25259
25260
25261
25262
25263
25264
25265
25266
25267
25268
25269
25270
25271
25272
25273
25274
25275
25276
25277
25278
25279
25280
25281
25282
25283
25284
25285
25286
25287
25288
25289
25290
25291
25292
25293
25294
25295
25296
25297
25298
25299
25300
25301
25302
25303
25304
25305
25306
25307
25308
25309
25310
25311
25312
25313
25314
25315
25316
25317
25318
25319
25320
25321
25322
25323
25324
25325
25326
25327
25328
25329
25330
25331
25332
25333
25334
25335
25336
25337
25338
25339
25340
25341
25342
25343
25344
25345
25346
25347
25348
25349
25350
25351
25352
25353
25354
25355
25356
25357
25358
25359
25360
25361
25362
25363
25364
25365
25366
25367
25368
25369
25370
25371
25372
25373
25374
25375
25376
25377
25378
25379
25380
25381
25382
25383
25384
25385
25386
25387
25388
25389
25390
25391
25392
25393
25394
25395
25396
25397
25398
25399
25400
25401
25402
25403
25404
25405
25406
25407
25408
25409
25410
25411
25412
25413
25414
25415
25416
25417
25418
25419
25420
25421
25422
25423
25424
25425
25426
25427
25428
25429
25430
25431
25432
25433
25434
25435
25436
25437
25438
25439
25440
25441
25442
25443
25444
25445
25446
25447
25448
25449
25450
25451
25452
25453
25454
25455
25456
25457
25458
25459
25460
25461
25462
25463
25464
25465
25466
25467
25468
25469
25470
25471
25472
25473
25474
25475
25476
25477
25478
25479
25480
25481
25482
25483
25484
25485
25486
25487
25488
25489
25490
25491
25492
25493
25494
25495
25496
25497
25498
25499
25500
25501
25502
25503
25504
25505
25506
25507
25508
25509
25510
25511
25512
25513
25514
25515
25516
25517
25518
25519
25520
25521
25522
25523
25524
25525
25526
25527
25528
25529
25530
25531
25532
25533
25534
25535
25536
25537
25538
25539
25540
25541
25542
25543
25544
25545
25546
25547
25548
25549
25550
25551
25552
25553
25554
25555
25556
25557
25558
25559
25560
25561
25562
25563
25564
25565
25566
25567
25568
25569
25570
25571
25572
25573
25574
25575
25576
25577
25578
25579
25580
25581
25582
25583
25584
25585
25586
25587
25588
25589
25590
25591
25592
25593
25594
25595
25596
25597
25598
25599
25600
25601
25602
25603
25604
25605
25606
25607
25608
25609
25610
25611
25612
25613
25614
25615
25616
25617
25618
25619
25620
25621
25622
25623
25624
25625
25626
25627
25628
25629
25630
25631
25632
25633
25634
25635
25636
25637
25638
25639
25640
25641
25642
25643
25644
25645
25646
25647
25648
25649
25650
25651
25652
25653
25654
25655
25656
25657
25658
25659
25660
25661
25662
25663
25664
25665
25666
25667
25668
25669
25670
25671
25672
25673
25674
25675
25676
25677
25678
25679
25680
25681
25682
25683
25684
25685
25686
25687
25688
25689
25690
25691
25692
25693
25694
25695
25696
25697
25698
25699
25700
25701
25702
25703
25704
25705
25706
25707
25708
25709
25710
25711
25712
25713
25714
25715
25716
25717
25718
25719
25720
25721
25722
25723
25724
25725
25726
25727
25728
25729
25730
25731
25732
25733
25734
25735
25736
25737
25738
25739
25740
25741
25742
25743
25744
25745
25746
25747
25748
25749
25750
25751
25752
25753
25754
25755
25756
25757
25758
25759
25760
25761
25762
25763
25764
25765
25766
25767
25768
25769
25770
25771
25772
25773
25774
25775
25776
25777
25778
25779
25780
25781
25782
25783
25784
25785
25786
25787
25788
25789
25790
25791
25792
25793
25794
25795
25796
25797
25798
25799
25800
25801
25802
25803
25804
25805
25806
25807
25808
25809
25810
25811
25812
25813
25814
25815
25816
25817
25818
25819
25820
25821
25822
25823
25824
25825
25826
25827
25828
25829
25830
25831
25832
25833
25834
25835
25836
25837
25838
25839
25840
25841
25842
25843
25844
25845
25846
25847
25848
25849
25850
25851
25852
25853
25854
25855
25856
25857
25858
25859
25860
25861
25862
25863
25864
25865
25866
25867
25868
25869
25870
25871
25872
25873
25874
25875
25876
25877
25878
25879
25880
25881
25882
25883
25884
25885
25886
25887
25888
25889
25890
25891
25892
25893
25894
25895
25896
25897
25898
25899
25900
25901
25902
25903
25904
25905
25906
25907
25908
25909
25910
25911
25912
25913
25914
25915
25916
25917
25918
25919
25920
25921
25922
25923
25924
25925
25926
25927
25928
25929
25930
25931
25932
25933
25934
25935
25936
25937
25938
25939
25940
25941
25942
25943
25944
25945
25946
25947
25948
25949
25950
25951
25952
25953
25954
25955
25956
25957
25958
25959
25960
25961
25962
25963
25964
25965
25966
25967
25968
25969
25970
25971
25972
25973
25974
25975
25976
25977
25978
25979
25980
25981
25982
25983
25984
25985
25986
25987
25988
25989
25990
25991
25992
25993
25994
25995
25996
25997
25998
25999
26000
26001
26002
26003
26004
26005
26006
26007
26008
26009
26010
26011
26012
26013
26014
26015
26016
26017
26018
26019
26020
26021
26022
26023
26024
26025
26026
26027
26028
26029
26030
26031
26032
26033
26034
26035
26036
26037
26038
26039
26040
26041
26042
26043
26044
26045
26046
26047
26048
26049
26050
26051
26052
26053
26054
26055
26056
26057
26058
26059
26060
26061
26062
26063
26064
26065
26066
26067
26068
26069
26070
26071
26072
26073
26074
26075
26076
26077
26078
26079
26080
26081
26082
26083
26084
26085
26086
26087
26088
26089
26090
26091
26092
26093
26094
26095
26096
26097
26098
26099
26100
26101
26102
26103
26104
26105
26106
26107
26108
26109
26110
26111
26112
26113
26114
26115
26116
26117
26118
26119
26120
26121
26122
26123
26124
26125
26126
26127
26128
26129
26130
26131
26132
26133
26134
26135
26136
26137
26138
26139
26140
26141
26142
26143
26144
26145
26146
26147
26148
26149
26150
26151
26152
26153
26154
26155
26156
26157
26158
26159
26160
26161
26162
26163
26164
26165
26166
26167
26168
26169
26170
26171
26172
26173
26174
26175
26176
26177
26178
26179
26180
26181
26182
26183
26184
26185
26186
26187
26188
26189
26190
26191
26192
26193
26194
26195
26196
26197
26198
26199
26200
26201
26202
26203
26204
26205
26206
26207
26208
26209
26210
26211
26212
26213
26214
26215
26216
26217
26218
26219
26220
26221
26222
26223
26224
26225
26226
26227
26228
26229
26230
26231
26232
26233
26234
26235
26236
26237
26238
26239
26240
26241
26242
26243
26244
26245
26246
26247
26248
26249
26250
26251
26252
26253
26254
26255
26256
26257
26258
26259
26260
26261
26262
26263
26264
26265
26266
26267
26268
26269
26270
26271
26272
26273
26274
26275
26276
26277
26278
26279
26280
26281
26282
26283
26284
26285
26286
26287
26288
26289
26290
26291
26292
26293
26294
26295
26296
26297
26298
26299
26300
26301
26302
26303
26304
26305
26306
26307
26308
26309
26310
26311
26312
26313
26314
26315
26316
26317
26318
26319
26320
26321
26322
26323
26324
26325
26326
26327
26328
26329
26330
26331
26332
26333
26334
26335
26336
26337
26338
26339
26340
26341
26342
26343
26344
26345
26346
26347
26348
26349
26350
26351
26352
26353
26354
26355
26356
26357
26358
26359
26360
26361
26362
26363
26364
26365
26366
26367
26368
26369
26370
26371
26372
26373
26374
26375
26376
26377
26378
26379
26380
26381
26382
26383
26384
26385
26386
26387
26388
26389
26390
26391
26392
26393
26394
26395
26396
26397
26398
26399
26400
26401
26402
26403
26404
26405
26406
26407
26408
26409
26410
26411
26412
26413
26414
26415
26416
26417
26418
26419
26420
26421
26422
26423
26424
26425
26426
26427
26428
26429
26430
26431
26432
26433
26434
26435
26436
26437
26438
26439
26440
26441
26442
26443
26444
26445
26446
26447
26448
26449
26450
26451
26452
26453
26454
26455
26456
26457
26458
26459
26460
26461
26462
26463
26464
26465
26466
26467
26468
26469
26470
26471
26472
26473
26474
26475
26476
26477
26478
26479
26480
26481
26482
26483
26484
26485
26486
26487
26488
26489
26490
26491
26492
26493
26494
26495
26496
26497
26498
26499
26500
26501
26502
26503
26504
26505
26506
26507
26508
26509
26510
26511
26512
26513
26514
26515
26516
26517
26518
26519
26520
26521
26522
26523
26524
26525
26526
26527
26528
26529
26530
26531
26532
26533
26534
26535
26536
26537
26538
26539
26540
26541
26542
26543
26544
26545
26546
26547
26548
26549
26550
26551
26552
26553
26554
26555
26556
26557
26558
26559
26560
26561
26562
26563
26564
26565
26566
26567
26568
26569
26570
26571
26572
26573
26574
26575
26576
26577
26578
26579
26580
26581
26582
26583
26584
26585
26586
26587
26588
26589
26590
26591
26592
26593
26594
26595
26596
26597
26598
26599
26600
26601
26602
26603
26604
26605
26606
26607
26608
26609
26610
26611
26612
26613
26614
26615
26616
26617
26618
26619
26620
26621
26622
26623
26624
26625
26626
26627
26628
26629
26630
26631
26632
26633
26634
26635
26636
26637
26638
26639
26640
26641
26642
26643
26644
26645
26646
26647
26648
26649
26650
26651
26652
26653
26654
26655
26656
26657
26658
26659
26660
26661
26662
26663
26664
26665
26666
26667
26668
26669
26670
26671
26672
26673
26674
26675
26676
26677
26678
26679
26680
26681
26682
26683
26684
26685
26686
26687
26688
26689
26690
26691
26692
26693
26694
26695
26696
26697
26698
26699
26700
26701
26702
26703
26704
26705
26706
26707
26708
26709
26710
26711
26712
26713
26714
26715
26716
26717
26718
26719
26720
26721
26722
26723
26724
26725
26726
26727
26728
26729
26730
26731
26732
26733
26734
26735
26736
26737
26738
26739
26740
26741
26742
26743
26744
26745
26746
26747
26748
26749
26750
26751
26752
26753
26754
26755
26756
26757
26758
26759
26760
26761
26762
26763
26764
26765
26766
26767
26768
26769
26770
26771
26772
26773
26774
26775
26776
26777
26778
26779
26780
26781
26782
26783
26784
26785
26786
26787
26788
26789
26790
26791
26792
26793
26794
26795
26796
26797
26798
26799
26800
26801
26802
26803
26804
26805
26806
26807
26808
26809
26810
26811
26812
26813
26814
26815
26816
26817
26818
26819
26820
26821
26822
26823
26824
26825
26826
26827
26828
26829
26830
26831
26832
26833
26834
26835
26836
26837
26838
26839
26840
26841
26842
26843
26844
26845
26846
26847
26848
26849
26850
26851
26852
26853
26854
26855
26856
26857
26858
26859
26860
26861
26862
26863
26864
26865
26866
26867
26868
26869
26870
26871
26872
26873
26874
26875
26876
26877
26878
26879
26880
26881
26882
26883
26884
26885
26886
26887
26888
26889
26890
26891
26892
26893
26894
26895
26896
26897
26898
26899
26900
26901
26902
26903
26904
26905
26906
26907
26908
26909
26910
26911
26912
26913
26914
26915
26916
26917
26918
26919
26920
26921
26922
26923
26924
26925
26926
26927
26928
26929
26930
26931
26932
26933
26934
26935
26936
26937
26938
26939
26940
26941
26942
26943
26944
26945
26946
26947
26948
26949
26950
26951
26952
26953
26954
26955
26956
26957
26958
26959
26960
26961
26962
26963
26964
26965
26966
26967
26968
26969
26970
26971
26972
26973
26974
26975
26976
26977
26978
26979
26980
26981
26982
26983
26984
26985
26986
26987
26988
26989
26990
26991
26992
26993
26994
26995
26996
26997
26998
26999
27000
27001
27002
27003
27004
27005
27006
27007
27008
27009
27010
27011
27012
27013
27014
27015
27016
27017
27018
27019
27020
27021
27022
27023
27024
27025
27026
27027
27028
27029
27030
27031
27032
27033
27034
27035
27036
27037
27038
27039
27040
27041
27042
27043
27044
27045
27046
27047
27048
27049
27050
27051
27052
27053
27054
27055
27056
27057
27058
27059
27060
27061
27062
27063
27064
27065
27066
27067
27068
27069
27070
27071
27072
27073
27074
27075
27076
27077
27078
27079
27080
27081
27082
27083
27084
27085
27086
27087
27088
27089
27090
27091
27092
27093
27094
27095
27096
27097
27098
27099
27100
27101
27102
27103
27104
27105
27106
27107
27108
27109
27110
27111
27112
27113
27114
27115
27116
27117
27118
27119
27120
27121
27122
27123
27124
27125
27126
27127
27128
27129
27130
27131
27132
27133
27134
27135
27136
27137
27138
27139
27140
27141
27142
27143
27144
27145
27146
27147
27148
27149
27150
27151
27152
27153
27154
27155
27156
27157
27158
27159
27160
27161
27162
27163
27164
27165
27166
27167
27168
27169
27170
27171
27172
27173
27174
27175
27176
27177
27178
27179
27180
27181
27182
27183
27184
27185
27186
27187
27188
27189
27190
27191
27192
27193
27194
27195
27196
27197
27198
27199
27200
27201
27202
27203
27204
27205
27206
27207
27208
27209
27210
27211
27212
27213
27214
27215
27216
27217
27218
27219
27220
27221
27222
27223
27224
27225
27226
27227
27228
27229
27230
27231
27232
27233
27234
27235
27236
27237
27238
27239
27240
27241
27242
27243
27244
27245
27246
27247
27248
27249
27250
27251
27252
27253
27254
27255
27256
27257
27258
27259
27260
27261
27262
27263
27264
27265
27266
27267
27268
27269
27270
27271
27272
27273
27274
27275
27276
27277
27278
27279
27280
27281
27282
27283
27284
27285
27286
27287
27288
27289
27290
27291
27292
27293
27294
27295
27296
27297
27298
27299
27300
27301
27302
27303
27304
27305
27306
27307
27308
27309
27310
27311
27312
27313
27314
27315
27316
27317
27318
27319
27320
27321
27322
27323
27324
27325
27326
27327
27328
27329
27330
27331
27332
27333
27334
27335
27336
27337
27338
27339
27340
27341
27342
27343
27344
27345
27346
27347
27348
27349
27350
27351
27352
27353
27354
27355
27356
27357
27358
27359
27360
27361
27362
27363
27364
27365
27366
27367
27368
27369
27370
27371
27372
27373
27374
27375
27376
27377
27378
27379
27380
27381
27382
27383
27384
27385
27386
27387
27388
27389
27390
27391
27392
27393
27394
27395
27396
27397
27398
27399
27400
27401
27402
27403
27404
27405
27406
27407
27408
27409
27410
27411
27412
27413
27414
27415
27416
27417
27418
27419
27420
27421
27422
27423
27424
27425
27426
27427
27428
27429
27430
27431
27432
27433
27434
27435
27436
27437
27438
27439
27440
27441
27442
27443
27444
27445
27446
27447
27448
27449
27450
27451
27452
27453
27454
27455
27456
27457
27458
27459
27460
27461
27462
27463
27464
27465
27466
27467
27468
27469
27470
27471
27472
27473
27474
27475
27476
27477
27478
27479
27480
27481
27482
27483
27484
27485
27486
27487
27488
27489
27490
27491
27492
27493
27494
27495
27496
27497
27498
27499
27500
27501
27502
27503
27504
27505
27506
27507
27508
27509
27510
27511
27512
27513
27514
27515
27516
27517
27518
27519
27520
27521
27522
27523
27524
27525
27526
27527
27528
27529
27530
27531
27532
27533
27534
27535
27536
27537
27538
27539
27540
27541
27542
27543
27544
27545
27546
27547
27548
27549
27550
27551
27552
27553
27554
27555
27556
27557
27558
27559
27560
27561
27562
27563
27564
27565
27566
27567
27568
27569
27570
27571
27572
27573
27574
27575
27576
27577
27578
27579
27580
27581
27582
27583
27584
27585
27586
27587
27588
27589
27590
27591
27592
27593
27594
27595
27596
27597
27598
27599
27600
27601
27602
27603
27604
27605
27606
27607
27608
27609
27610
27611
27612
27613
27614
27615
27616
27617
27618
27619
27620
27621
27622
27623
27624
27625
27626
27627
27628
27629
27630
27631
27632
27633
27634
27635
27636
27637
27638
27639
27640
27641
27642
27643
27644
27645
27646
27647
27648
27649
27650
27651
27652
27653
27654
27655
27656
27657
27658
27659
27660
27661
27662
27663
27664
27665
27666
27667
27668
27669
27670
27671
27672
27673
27674
27675
27676
27677
27678
27679
27680
27681
27682
27683
27684
27685
27686
27687
27688
27689
27690
27691
27692
27693
27694
27695
27696
27697
27698
27699
27700
27701
27702
27703
27704
27705
27706
27707
27708
27709
27710
27711
27712
27713
27714
27715
27716
27717
27718
27719
27720
27721
27722
27723
27724
27725
27726
27727
27728
27729
27730
27731
27732
27733
27734
27735
27736
27737
27738
27739
27740
27741
27742
27743
27744
27745
27746
27747
27748
27749
27750
27751
27752
27753
27754
27755
27756
27757
27758
27759
27760
27761
27762
27763
27764
27765
27766
27767
27768
27769
27770
27771
27772
27773
27774
27775
27776
27777
27778
27779
27780
27781
27782
27783
27784
27785
27786
27787
27788
27789
27790
27791
27792
27793
27794
27795
27796
27797
27798
27799
27800
27801
27802
27803
27804
27805
27806
27807
27808
27809
27810
27811
27812
27813
27814
27815
27816
27817
27818
27819
27820
27821
27822
27823
27824
27825
27826
27827
27828
27829
27830
27831
27832
27833
27834
27835
27836
27837
27838
27839
27840
27841
27842
27843
27844
27845
27846
27847
27848
27849
27850
27851
27852
27853
27854
27855
27856
27857
27858
27859
27860
27861
27862
27863
27864
27865
27866
27867
27868
27869
27870
27871
27872
27873
27874
27875
27876
27877
27878
27879
27880
27881
27882
27883
27884
27885
27886
27887
27888
27889
27890
27891
27892
27893
27894
27895
27896
27897
27898
27899
27900
27901
27902
27903
27904
27905
27906
27907
27908
27909
27910
27911
27912
27913
27914
27915
27916
27917
27918
27919
27920
27921
27922
27923
27924
27925
27926
27927
27928
27929
27930
27931
27932
27933
27934
27935
27936
27937
27938
27939
27940
27941
27942
27943
27944
27945
27946
27947
27948
27949
27950
27951
27952
27953
27954
27955
27956
27957
27958
27959
27960
27961
27962
27963
27964
27965
27966
27967
27968
27969
27970
27971
27972
27973
27974
27975
27976
27977
27978
27979
27980
27981
27982
27983
27984
27985
27986
27987
27988
27989
27990
27991
27992
27993
27994
27995
27996
27997
27998
27999
28000
28001
28002
28003
28004
28005
28006
28007
28008
28009
28010
28011
28012
28013
28014
28015
28016
28017
28018
28019
28020
28021
28022
28023
28024
28025
28026
28027
28028
28029
28030
28031
28032
28033
28034
28035
28036
28037
28038
28039
28040
28041
28042
28043
28044
28045
28046
28047
28048
28049
28050
28051
28052
28053
28054
28055
28056
28057
28058
28059
28060
28061
28062
28063
28064
28065
28066
28067
28068
28069
28070
28071
28072
28073
28074
28075
28076
28077
28078
28079
28080
28081
28082
28083
28084
28085
28086
28087
28088
28089
28090
28091
28092
28093
28094
28095
28096
28097
28098
28099
28100
28101
28102
28103
28104
28105
28106
28107
28108
28109
28110
28111
28112
28113
28114
28115
28116
28117
28118
28119
28120
28121
28122
28123
28124
28125
28126
28127
28128
28129
28130
28131
28132
28133
28134
28135
28136
28137
28138
28139
28140
28141
28142
28143
28144
28145
28146
28147
28148
28149
28150
28151
28152
28153
28154
28155
28156
28157
28158
28159
28160
28161
28162
28163
28164
28165
28166
28167
28168
28169
28170
28171
28172
28173
28174
28175
28176
28177
28178
28179
28180
28181
28182
28183
28184
28185
28186
28187
28188
28189
28190
28191
28192
28193
28194
28195
28196
28197
28198
28199
28200
28201
28202
28203
28204
28205
28206
28207
28208
28209
28210
28211
28212
28213
28214
28215
28216
28217
28218
28219
28220
28221
28222
28223
28224
28225
28226
28227
28228
28229
28230
28231
28232
28233
28234
28235
28236
28237
28238
28239
28240
28241
28242
28243
28244
28245
28246
28247
28248
28249
28250
28251
28252
28253
28254
28255
28256
28257
28258
28259
28260
28261
28262
28263
28264
28265
28266
28267
28268
28269
28270
28271
28272
28273
28274
28275
28276
28277
28278
28279
28280
28281
28282
28283
28284
28285
28286
28287
28288
28289
28290
28291
28292
28293
28294
28295
28296
28297
28298
28299
28300
28301
28302
28303
28304
28305
28306
28307
28308
28309
28310
28311
28312
28313
28314
28315
28316
28317
28318
28319
28320
28321
28322
28323
28324
28325
28326
28327
28328
28329
28330
28331
28332
28333
28334
28335
28336
28337
28338
28339
28340
28341
28342
28343
28344
28345
28346
28347
28348
28349
28350
28351
28352
28353
28354
28355
28356
28357
28358
28359
28360
28361
28362
28363
28364
28365
28366
28367
28368
28369
28370
28371
28372
28373
28374
28375
28376
28377
28378
28379
28380
28381
28382
28383
28384
28385
28386
28387
28388
28389
28390
28391
28392
28393
28394
28395
28396
28397
28398
28399
28400
28401
28402
28403
28404
28405
28406
28407
28408
28409
28410
28411
28412
28413
28414
28415
28416
28417
28418
28419
28420
28421
28422
28423
28424
28425
28426
28427
28428
28429
28430
28431
28432
28433
28434
28435
28436
28437
28438
28439
28440
28441
28442
28443
28444
28445
28446
28447
28448
28449
28450
28451
28452
28453
28454
28455
28456
28457
28458
28459
28460
28461
28462
28463
28464
28465
28466
28467
28468
28469
28470
28471
28472
28473
28474
28475
28476
28477
28478
28479
28480
28481
28482
28483
28484
28485
28486
28487
28488
28489
28490
28491
28492
28493
28494
28495
28496
28497
28498
28499
28500
28501
28502
28503
28504
28505
28506
28507
28508
28509
28510
28511
28512
28513
28514
28515
28516
28517
28518
28519
28520
28521
28522
28523
28524
28525
28526
28527
28528
28529
28530
28531
28532
28533
28534
28535
28536
28537
28538
28539
28540
28541
28542
28543
28544
28545
28546
28547
28548
28549
28550
28551
28552
28553
28554
28555
28556
28557
28558
28559
28560
28561
28562
28563
28564
28565
28566
28567
28568
28569
28570
28571
28572
28573
28574
28575
28576
28577
28578
28579
28580
28581
28582
28583
28584
28585
28586
28587
28588
28589
28590
28591
28592
28593
28594
28595
28596
28597
28598
28599
28600
28601
28602
28603
28604
28605
28606
28607
28608
28609
28610
28611
28612
28613
28614
28615
28616
28617
28618
28619
28620
28621
28622
28623
28624
28625
28626
28627
28628
28629
28630
28631
28632
28633
28634
28635
28636
28637
28638
28639
28640
28641
28642
28643
28644
28645
28646
28647
28648
28649
28650
28651
28652
28653
28654
28655
28656
28657
28658
28659
28660
28661
28662
28663
28664
28665
28666
28667
28668
28669
28670
28671
28672
28673
28674
28675
28676
28677
28678
28679
28680
28681
28682
28683
28684
28685
28686
28687
28688
28689
28690
28691
28692
28693
28694
28695
28696
28697
28698
28699
28700
28701
28702
28703
28704
28705
28706
28707
28708
28709
28710
28711
28712
28713
28714
28715
28716
28717
28718
28719
28720
28721
28722
28723
28724
28725
28726
28727
28728
28729
28730
28731
28732
28733
28734
28735
28736
28737
28738
28739
28740
28741
28742
28743
28744
28745
28746
28747
28748
28749
28750
28751
28752
28753
28754
28755
28756
28757
28758
28759
28760
28761
28762
28763
28764
28765
28766
28767
28768
28769
28770
28771
28772
28773
28774
28775
28776
28777
28778
28779
28780
28781
28782
28783
28784
28785
28786
28787
28788
28789
28790
28791
28792
28793
28794
28795
28796
28797
28798
28799
28800
28801
28802
28803
28804
28805
28806
28807
28808
28809
28810
28811
28812
28813
28814
28815
28816
28817
28818
28819
28820
28821
28822
28823
28824
28825
28826
28827
28828
28829
28830
28831
28832
28833
28834
28835
28836
28837
28838
28839
28840
28841
28842
28843
28844
28845
28846
28847
28848
28849
28850
28851
28852
28853
28854
28855
28856
28857
28858
28859
28860
28861
28862
28863
28864
28865
28866
28867
28868
28869
28870
28871
28872
28873
28874
28875
28876
28877
28878
28879
28880
28881
28882
28883
28884
28885
28886
28887
28888
28889
28890
28891
28892
28893
28894
28895
28896
28897
28898
28899
28900
28901
28902
28903
28904
28905
28906
28907
28908
28909
28910
28911
28912
28913
28914
28915
28916
28917
28918
28919
28920
28921
28922
28923
28924
28925
28926
28927
28928
28929
28930
28931
28932
28933
28934
28935
28936
28937
28938
28939
28940
28941
28942
28943
28944
28945
28946
28947
28948
28949
28950
28951
28952
28953
28954
28955
28956
28957
28958
28959
28960
28961
28962
28963
28964
28965
28966
28967
28968
28969
28970
28971
28972
28973
28974
28975
28976
28977
28978
28979
28980
28981
28982
28983
28984
28985
28986
28987
28988
28989
28990
28991
28992
28993
28994
28995
28996
28997
28998
28999
29000
29001
29002
29003
29004
29005
29006
29007
29008
29009
29010
29011
29012
29013
29014
29015
29016
29017
29018
29019
29020
29021
29022
29023
29024
29025
29026
29027
29028
29029
29030
29031
29032
29033
29034
29035
29036
29037
29038
29039
29040
29041
29042
29043
29044
29045
29046
29047
29048
29049
29050
29051
29052
29053
29054
29055
29056
29057
29058
29059
29060
29061
29062
29063
29064
29065
29066
29067
29068
29069
29070
29071
29072
29073
29074
29075
29076
29077
29078
29079
29080
29081
29082
29083
29084
29085
29086
29087
29088
29089
29090
29091
29092
29093
29094
29095
29096
29097
29098
29099
29100
29101
29102
29103
29104
29105
29106
29107
29108
29109
29110
29111
29112
29113
29114
29115
29116
29117
29118
29119
29120
29121
29122
29123
29124
29125
29126
29127
29128
29129
29130
29131
29132
29133
29134
29135
29136
29137
29138
29139
29140
29141
29142
29143
29144
29145
29146
29147
29148
29149
29150
29151
29152
29153
29154
29155
29156
29157
29158
29159
29160
29161
29162
29163
29164
29165
29166
29167
29168
29169
29170
29171
29172
29173
29174
29175
29176
29177
29178
29179
29180
29181
29182
29183
29184
29185
29186
29187
29188
29189
29190
29191
29192
29193
29194
29195
29196
29197
29198
29199
29200
29201
29202
29203
29204
29205
29206
29207
29208
29209
29210
29211
29212
29213
29214
29215
29216
29217
29218
29219
29220
29221
29222
29223
29224
29225
29226
29227
29228
29229
29230
29231
29232
29233
29234
29235
29236
29237
29238
29239
29240
29241
29242
29243
29244
29245
29246
29247
29248
29249
29250
29251
29252
29253
29254
29255
29256
29257
29258
29259
29260
29261
29262
29263
29264
29265
29266
29267
29268
29269
29270
29271
29272
29273
29274
29275
29276
29277
29278
29279
29280
29281
29282
29283
29284
29285
29286
29287
29288
29289
29290
29291
29292
29293
29294
29295
29296
29297
29298
29299
29300
29301
29302
29303
29304
29305
29306
29307
29308
29309
29310
29311
29312
29313
29314
29315
29316
29317
29318
29319
29320
29321
29322
29323
29324
29325
29326
29327
29328
29329
29330
29331
29332
29333
29334
29335
29336
29337
29338
29339
29340
29341
29342
29343
29344
29345
29346
29347
29348
29349
29350
29351
29352
29353
29354
29355
29356
29357
29358
29359
29360
29361
29362
29363
29364
29365
29366
29367
29368
29369
29370
29371
29372
29373
29374
29375
29376
29377
29378
29379
29380
29381
29382
29383
29384
29385
29386
29387
29388
29389
29390
29391
29392
29393
29394
29395
29396
29397
29398
29399
29400
29401
29402
29403
29404
29405
29406
29407
29408
29409
29410
29411
29412
29413
29414
29415
29416
29417
29418
29419
29420
29421
29422
29423
29424
29425
29426
29427
29428
29429
29430
29431
29432
29433
29434
29435
29436
29437
29438
29439
29440
29441
29442
29443
29444
29445
29446
29447
29448
29449
29450
29451
29452
29453
29454
29455
29456
29457
29458
29459
29460
29461
29462
29463
29464
29465
29466
29467
29468
29469
29470
29471
29472
29473
29474
29475
29476
29477
29478
29479
29480
29481
29482
29483
29484
29485
29486
29487
29488
29489
29490
29491
29492
29493
29494
29495
29496
29497
29498
29499
29500
29501
29502
29503
29504
29505
29506
29507
29508
29509
29510
29511
29512
29513
29514
29515
29516
29517
29518
29519
29520
29521
29522
29523
29524
29525
29526
29527
29528
29529
29530
29531
29532
29533
29534
29535
29536
29537
29538
29539
29540
29541
29542
29543
29544
29545
29546
29547
29548
29549
29550
29551
29552
29553
29554
29555
29556
29557
29558
29559
29560
29561
29562
29563
29564
29565
29566
29567
29568
29569
29570
29571
29572
29573
29574
29575
29576
29577
29578
29579
29580
29581
29582
29583
29584
29585
29586
29587
29588
29589
29590
29591
29592
29593
29594
29595
29596
29597
29598
29599
29600
29601
29602
29603
29604
29605
29606
29607
29608
29609
29610
29611
29612
29613
29614
29615
29616
29617
29618
29619
29620
29621
29622
29623
29624
29625
29626
29627
29628
29629
29630
29631
29632
29633
29634
29635
29636
29637
29638
29639
29640
29641
29642
29643
29644
29645
29646
29647
29648
29649
29650
29651
29652
29653
29654
29655
29656
29657
29658
29659
29660
29661
29662
29663
29664
29665
29666
29667
29668
29669
29670
29671
29672
29673
29674
29675
29676
29677
29678
29679
29680
29681
29682
29683
29684
29685
29686
29687
29688
29689
29690
29691
29692
29693
29694
29695
29696
29697
29698
29699
29700
29701
29702
29703
29704
29705
29706
29707
29708
29709
29710
29711
29712
29713
29714
29715
29716
29717
29718
29719
29720
29721
29722
29723
29724
29725
29726
29727
29728
29729
29730
29731
29732
29733
29734
29735
29736
29737
29738
29739
29740
29741
29742
29743
29744
29745
29746
29747
29748
29749
29750
29751
29752
29753
29754
29755
29756
29757
29758
29759
29760
29761
29762
29763
29764
29765
29766
29767
29768
29769
29770
29771
29772
29773
29774
29775
29776
29777
29778
29779
29780
29781
29782
29783
29784
29785
29786
29787
29788
29789
29790
29791
29792
29793
29794
29795
29796
29797
29798
29799
29800
29801
29802
29803
29804
29805
29806
29807
29808
29809
29810
29811
29812
29813
29814
29815
29816
29817
29818
29819
29820
29821
29822
29823
29824
29825
29826
29827
29828
29829
29830
29831
29832
29833
29834
29835
29836
29837
29838
29839
29840
29841
29842
29843
29844
29845
29846
29847
29848
29849
29850
29851
29852
29853
29854
29855
29856
29857
29858
29859
29860
29861
29862
29863
29864
29865
29866
29867
29868
29869
29870
29871
29872
29873
29874
29875
29876
29877
29878
29879
29880
29881
29882
29883
29884
29885
29886
29887
29888
29889
29890
29891
29892
29893
29894
29895
29896
29897
29898
29899
29900
29901
29902
29903
29904
29905
29906
29907
29908
29909
29910
29911
29912
29913
29914
29915
29916
29917
29918
29919
29920
29921
29922
29923
29924
29925
29926
29927
29928
29929
29930
29931
29932
29933
29934
29935
29936
29937
29938
29939
29940
29941
29942
29943
29944
29945
29946
29947
29948
29949
29950
29951
29952
29953
29954
29955
29956
29957
29958
29959
29960
29961
29962
29963
29964
29965
29966
29967
29968
29969
29970
29971
29972
29973
29974
29975
29976
29977
29978
29979
29980
29981
29982
29983
29984
29985
29986
29987
29988
29989
29990
29991
29992
29993
29994
29995
29996
29997
29998
29999
30000
30001
30002
30003
30004
30005
30006
30007
30008
30009
30010
30011
30012
30013
30014
30015
30016
30017
30018
30019
30020
30021
30022
30023
30024
30025
30026
30027
30028
30029
30030
30031
30032
30033
30034
30035
30036
30037
30038
30039
30040
30041
30042
30043
30044
30045
30046
30047
30048
30049
30050
30051
30052
30053
30054
30055
30056
30057
30058
30059
30060
30061
30062
30063
30064
30065
30066
30067
30068
30069
30070
30071
30072
30073
30074
30075
30076
30077
30078
30079
30080
30081
30082
30083
30084
30085
30086
30087
30088
30089
30090
30091
30092
30093
30094
30095
30096
30097
30098
30099
30100
30101
30102
30103
30104
30105
30106
30107
30108
30109
30110
30111
30112
30113
30114
30115
30116
30117
30118
30119
30120
30121
30122
30123
30124
30125
30126
30127
30128
30129
30130
30131
30132
30133
30134
30135
30136
30137
30138
30139
30140
30141
30142
30143
30144
30145
30146
30147
30148
30149
30150
30151
30152
30153
30154
30155
30156
30157
30158
30159
30160
30161
30162
30163
30164
30165
30166
30167
30168
30169
30170
30171
30172
30173
30174
30175
30176
30177
30178
30179
30180
30181
30182
30183
30184
30185
30186
30187
30188
30189
30190
30191
30192
30193
30194
30195
30196
30197
30198
30199
30200
30201
30202
30203
30204
30205
30206
30207
30208
30209
30210
30211
30212
30213
30214
30215
30216
30217
30218
30219
30220
30221
30222
30223
30224
30225
30226
30227
30228
30229
30230
30231
30232
30233
30234
30235
30236
30237
30238
30239
30240
30241
30242
30243
30244
30245
30246
30247
30248
30249
30250
30251
30252
30253
30254
30255
30256
30257
30258
30259
30260
30261
30262
30263
30264
30265
30266
30267
30268
30269
30270
30271
30272
30273
30274
30275
30276
30277
30278
30279
30280
30281
30282
30283
30284
30285
30286
30287
30288
30289
30290
30291
30292
30293
30294
30295
30296
30297
30298
30299
30300
30301
30302
30303
30304
30305
30306
30307
30308
30309
30310
30311
30312
30313
30314
30315
30316
30317
30318
30319
30320
30321
30322
30323
30324
30325
30326
30327
30328
30329
30330
30331
30332
30333
30334
30335
30336
30337
30338
30339
30340
30341
30342
30343
30344
30345
30346
30347
30348
30349
30350
30351
30352
30353
30354
30355
30356
30357
30358
30359
30360
30361
30362
30363
30364
30365
30366
30367
30368
30369
30370
30371
30372
30373
30374
30375
30376
30377
30378
30379
30380
30381
30382
30383
30384
30385
30386
30387
30388
30389
30390
30391
30392
30393
30394
30395
30396
30397
30398
30399
30400
30401
30402
30403
30404
30405
30406
30407
30408
30409
30410
30411
30412
30413
30414
30415
30416
30417
30418
30419
30420
30421
30422
30423
30424
30425
30426
30427
30428
30429
30430
30431
30432
30433
30434
30435
30436
30437
30438
30439
30440
30441
30442
30443
30444
30445
30446
30447
30448
30449
30450
30451
30452
30453
30454
30455
30456
30457
30458
30459
30460
30461
30462
30463
30464
30465
30466
30467
30468
30469
30470
30471
30472
30473
30474
30475
30476
30477
30478
30479
30480
30481
30482
30483
30484
30485
30486
30487
30488
30489
30490
30491
30492
30493
30494
30495
30496
30497
30498
30499
30500
30501
30502
30503
30504
30505
30506
30507
30508
30509
30510
30511
30512
30513
30514
30515
30516
30517
30518
30519
30520
30521
30522
30523
30524
30525
30526
30527
30528
30529
30530
30531
30532
30533
30534
30535
30536
30537
30538
30539
30540
30541
30542
30543
30544
30545
30546
30547
30548
30549
30550
30551
30552
30553
30554
30555
30556
30557
30558
30559
30560
30561
30562
30563
30564
30565
30566
30567
30568
30569
30570
30571
30572
30573
30574
30575
30576
30577
30578
30579
30580
30581
30582
30583
30584
30585
30586
30587
30588
30589
30590
30591
30592
30593
30594
30595
30596
30597
30598
30599
30600
30601
30602
30603
30604
30605
30606
30607
30608
30609
30610
30611
30612
30613
30614
30615
30616
30617
30618
30619
30620
30621
30622
30623
30624
30625
30626
30627
30628
30629
30630
30631
30632
30633
30634
30635
30636
30637
30638
30639
30640
30641
30642
30643
30644
30645
30646
30647
30648
30649
30650
30651
30652
30653
30654
30655
30656
30657
30658
30659
30660
30661
30662
30663
30664
30665
30666
30667
30668
30669
30670
30671
30672
30673
30674
30675
30676
30677
30678
30679
30680
30681
30682
30683
30684
30685
30686
30687
30688
30689
30690
30691
30692
30693
30694
30695
30696
30697
30698
30699
30700
30701
30702
30703
30704
30705
30706
30707
30708
30709
30710
30711
30712
30713
30714
30715
30716
30717
30718
30719
30720
30721
30722
30723
30724
30725
30726
30727
30728
30729
30730
30731
30732
30733
30734
30735
30736
30737
30738
30739
30740
30741
30742
30743
30744
30745
30746
30747
30748
30749
30750
30751
30752
30753
30754
30755
30756
30757
30758
30759
30760
30761
30762
30763
30764
30765
30766
30767
30768
30769
30770
30771
30772
30773
30774
30775
30776
30777
30778
30779
30780
30781
30782
30783
30784
30785
30786
30787
30788
30789
30790
30791
30792
30793
30794
30795
30796
30797
30798
30799
30800
30801
30802
30803
30804
30805
30806
30807
30808
30809
30810
30811
30812
30813
30814
30815
30816
30817
30818
30819
30820
30821
30822
30823
30824
30825
30826
30827
30828
30829
30830
30831
30832
30833
30834
30835
30836
30837
30838
30839
30840
30841
30842
30843
30844
30845
30846
30847
30848
30849
30850
30851
30852
30853
30854
30855
30856
30857
30858
30859
30860
30861
30862
30863
30864
30865
30866
30867
30868
30869
30870
30871
30872
30873
30874
30875
30876
30877
30878
30879
30880
30881
30882
30883
30884
30885
30886
30887
30888
30889
30890
30891
30892
30893
30894
30895
30896
30897
30898
30899
30900
30901
30902
30903
30904
30905
30906
30907
30908
30909
30910
30911
30912
30913
30914
30915
30916
30917
30918
30919
30920
30921
30922
30923
30924
30925
30926
30927
30928
30929
30930
30931
30932
30933
30934
30935
30936
30937
30938
30939
30940
30941
30942
30943
30944
30945
30946
30947
30948
30949
30950
30951
30952
30953
30954
30955
30956
30957
30958
30959
30960
30961
30962
30963
30964
30965
30966
30967
30968
30969
30970
30971
30972
30973
30974
30975
30976
30977
30978
30979
30980
30981
30982
30983
30984
30985
30986
30987
30988
30989
30990
30991
30992
30993
30994
30995
30996
30997
30998
30999
31000
31001
31002
31003
31004
31005
31006
31007
31008
31009
31010
31011
31012
31013
31014
31015
31016
31017
31018
31019
31020
31021
31022
31023
31024
31025
31026
31027
31028
31029
31030
31031
31032
31033
31034
31035
31036
31037
31038
31039
31040
31041
31042
31043
31044
31045
31046
31047
31048
31049
31050
31051
31052
31053
31054
31055
31056
31057
31058
31059
31060
31061
31062
31063
31064
31065
31066
31067
31068
31069
31070
31071
31072
31073
31074
31075
31076
31077
31078
31079
31080
31081
31082
31083
31084
31085
31086
31087
31088
31089
31090
31091
31092
31093
31094
31095
31096
31097
31098
31099
31100
31101
31102
31103
31104
31105
31106
31107
31108
31109
31110
31111
31112
31113
31114
31115
31116
31117
31118
31119
31120
31121
31122
31123
31124
31125
31126
31127
31128
31129
31130
31131
31132
31133
31134
31135
31136
31137
31138
31139
31140
31141
31142
31143
31144
31145
31146
31147
31148
31149
31150
31151
31152
31153
31154
31155
31156
31157
31158
31159
31160
31161
31162
31163
31164
31165
31166
31167
31168
31169
31170
31171
31172
31173
31174
31175
31176
31177
31178
31179
31180
31181
31182
31183
31184
31185
31186
31187
31188
31189
31190
31191
31192
31193
31194
31195
31196
31197
31198
31199
31200
31201
31202
31203
31204
31205
31206
31207
31208
31209
31210
31211
31212
31213
31214
31215
31216
31217
31218
31219
31220
31221
31222
31223
31224
31225
31226
31227
31228
31229
31230
31231
31232
31233
31234
31235
31236
31237
31238
31239
31240
31241
31242
31243
31244
31245
31246
31247
31248
31249
31250
31251
31252
31253
31254
31255
31256
31257
31258
31259
31260
31261
31262
31263
31264
31265
31266
31267
31268
31269
31270
31271
31272
31273
31274
31275
31276
31277
31278
31279
31280
31281
31282
31283
31284
31285
31286
31287
31288
31289
31290
31291
31292
31293
31294
31295
31296
31297
31298
31299
31300
31301
31302
31303
31304
31305
31306
31307
31308
31309
31310
31311
31312
31313
31314
31315
31316
31317
31318
31319
31320
31321
31322
31323
31324
31325
31326
31327
31328
31329
31330
31331
31332
31333
31334
31335
31336
31337
31338
31339
31340
31341
31342
31343
31344
31345
31346
31347
31348
31349
31350
31351
31352
31353
31354
31355
31356
31357
31358
31359
31360
31361
31362
31363
31364
31365
31366
31367
31368
31369
31370
31371
31372
31373
31374
31375
31376
31377
31378
31379
31380
31381
31382
31383
31384
31385
31386
31387
31388
31389
31390
31391
31392
31393
31394
31395
31396
31397
31398
31399
31400
31401
31402
31403
31404
31405
31406
31407
31408
31409
31410
31411
31412
31413
31414
31415
31416
31417
31418
31419
31420
31421
31422
31423
31424
31425
31426
31427
31428
31429
31430
31431
31432
31433
31434
31435
31436
31437
31438
31439
31440
31441
31442
31443
31444
31445
31446
31447
31448
31449
31450
31451
31452
31453
31454
31455
31456
31457
31458
31459
31460
31461
31462
31463
31464
31465
31466
31467
31468
31469
31470
31471
31472
31473
31474
31475
31476
31477
31478
31479
31480
31481
31482
31483
31484
31485
31486
31487
31488
31489
31490
31491
31492
31493
31494
31495
31496
31497
31498
31499
31500
31501
31502
31503
31504
31505
31506
31507
31508
31509
31510
31511
31512
31513
31514
31515
31516
31517
31518
31519
31520
31521
31522
31523
31524
31525
31526
31527
31528
31529
31530
31531
31532
31533
31534
31535
31536
31537
31538
31539
31540
31541
31542
31543
31544
31545
31546
31547
31548
31549
31550
31551
31552
31553
31554
31555
31556
31557
31558
31559
31560
31561
31562
31563
31564
31565
31566
31567
31568
31569
31570
31571
31572
31573
31574
31575
31576
31577
31578
31579
31580
31581
31582
31583
31584
31585
31586
31587
31588
31589
31590
31591
31592
31593
31594
31595
31596
31597
31598
31599
31600
31601
31602
31603
31604
31605
31606
31607
31608
31609
31610
31611
31612
31613
31614
31615
31616
31617
31618
31619
31620
31621
31622
31623
31624
31625
31626
31627
31628
31629
31630
31631
31632
31633
31634
31635
31636
31637
31638
31639
31640
31641
31642
31643
31644
31645
31646
31647
31648
31649
31650
31651
31652
31653
31654
31655
31656
31657
31658
31659
31660
31661
31662
31663
31664
31665
31666
31667
31668
31669
31670
31671
31672
31673
31674
31675
31676
31677
31678
31679
31680
31681
31682
31683
31684
31685
31686
31687
31688
31689
31690
31691
31692
31693
31694
31695
31696
31697
31698
31699
31700
31701
31702
31703
31704
31705
31706
31707
31708
31709
31710
31711
31712
31713
31714
31715
31716
31717
31718
31719
31720
31721
31722
31723
31724
31725
31726
31727
31728
31729
31730
31731
31732
31733
31734
31735
31736
31737
31738
31739
31740
31741
31742
31743
31744
31745
31746
31747
31748
31749
31750
31751
31752
31753
31754
31755
31756
31757
31758
31759
31760
31761
31762
31763
31764
31765
31766
31767
31768
31769
31770
31771
31772
31773
31774
31775
31776
31777
31778
31779
31780
31781
31782
31783
31784
31785
31786
31787
31788
31789
31790
31791
31792
31793
31794
31795
31796
31797
31798
31799
31800
31801
31802
31803
31804
31805
31806
31807
31808
31809
31810
31811
31812
31813
31814
31815
31816
31817
31818
31819
31820
31821
31822
31823
31824
31825
31826
31827
31828
31829
31830
31831
31832
31833
31834
31835
31836
31837
31838
31839
31840
31841
31842
31843
31844
31845
31846
31847
31848
31849
31850
31851
31852
31853
31854
31855
31856
31857
31858
31859
31860
31861
31862
31863
31864
31865
31866
31867
31868
31869
31870
31871
31872
31873
31874
31875
31876
31877
31878
31879
31880
31881
31882
31883
31884
31885
31886
31887
31888
31889
31890
31891
31892
31893
31894
31895
31896
31897
31898
31899
31900
31901
31902
31903
31904
31905
31906
31907
31908
31909
31910
31911
31912
31913
31914
31915
31916
31917
31918
31919
31920
31921
31922
31923
31924
31925
31926
31927
31928
31929
31930
31931
31932
31933
31934
31935
31936
31937
31938
31939
31940
31941
31942
31943
31944
31945
31946
31947
31948
31949
31950
31951
31952
31953
31954
31955
31956
31957
31958
31959
31960
31961
31962
31963
31964
31965
31966
31967
31968
31969
31970
31971
31972
31973
31974
31975
31976
31977
31978
31979
31980
31981
31982
31983
31984
31985
31986
31987
31988
31989
31990
31991
31992
31993
31994
31995
31996
31997
31998
31999
32000
32001
32002
32003
32004
32005
32006
32007
32008
32009
32010
32011
32012
32013
32014
32015
32016
32017
32018
32019
32020
32021
32022
32023
32024
32025
32026
32027
32028
32029
32030
32031
32032
32033
32034
32035
32036
32037
32038
32039
32040
32041
32042
32043
32044
32045
32046
32047
32048
32049
32050
32051
32052
32053
32054
32055
32056
32057
32058
32059
32060
32061
32062
32063
32064
32065
32066
32067
32068
32069
32070
32071
32072
32073
32074
32075
32076
32077
32078
32079
32080
32081
32082
32083
32084
32085
32086
32087
32088
32089
32090
32091
32092
32093
32094
32095
32096
32097
32098
32099
32100
32101
32102
32103
32104
32105
32106
32107
32108
32109
32110
32111
32112
32113
32114
32115
32116
32117
32118
32119
32120
32121
32122
32123
32124
32125
32126
32127
32128
32129
32130
32131
32132
32133
32134
32135
32136
32137
32138
32139
32140
32141
32142
32143
32144
32145
32146
32147
32148
32149
32150
32151
32152
32153
32154
32155
32156
32157
32158
32159
32160
32161
32162
32163
32164
32165
32166
32167
32168
32169
32170
32171
32172
32173
32174
32175
32176
32177
32178
32179
32180
32181
32182
32183
32184
32185
32186
32187
32188
32189
32190
32191
32192
32193
32194
32195
32196
32197
32198
32199
32200
32201
32202
32203
32204
32205
32206
32207
32208
32209
32210
32211
32212
32213
32214
32215
32216
32217
32218
32219
32220
32221
32222
32223
32224
32225
32226
32227
32228
32229
32230
32231
32232
32233
32234
32235
32236
32237
32238
32239
32240
32241
32242
32243
32244
32245
32246
32247
32248
32249
32250
32251
32252
32253
32254
32255
32256
32257
32258
32259
32260
32261
32262
32263
32264
32265
32266
32267
32268
32269
32270
32271
32272
32273
32274
32275
32276
32277
32278
32279
32280
32281
32282
32283
32284
32285
32286
32287
32288
32289
32290
32291
32292
32293
32294
32295
32296
32297
32298
32299
32300
32301
32302
32303
32304
32305
32306
32307
32308
32309
32310
32311
32312
32313
32314
32315
32316
32317
32318
32319
32320
32321
32322
32323
32324
32325
32326
32327
32328
32329
32330
32331
32332
32333
32334
32335
32336
32337
32338
32339
32340
32341
32342
32343
32344
32345
32346
32347
32348
32349
32350
32351
32352
32353
32354
32355
32356
32357
32358
32359
32360
32361
32362
32363
32364
32365
32366
32367
32368
32369
32370
32371
32372
32373
32374
32375
32376
32377
32378
32379
32380
32381
32382
32383
32384
32385
32386
32387
32388
32389
32390
32391
32392
32393
32394
32395
32396
32397
32398
32399
32400
32401
32402
32403
32404
32405
32406
32407
32408
32409
32410
32411
32412
32413
32414
32415
32416
32417
32418
32419
32420
32421
32422
32423
32424
32425
32426
32427
32428
32429
32430
32431
32432
32433
32434
32435
32436
32437
32438
32439
32440
32441
32442
32443
32444
32445
32446
32447
32448
32449
32450
32451
32452
32453
32454
32455
32456
32457
32458
32459
32460
32461
32462
32463
32464
32465
32466
32467
32468
32469
32470
32471
32472
32473
32474
32475
32476
32477
32478
32479
32480
32481
32482
32483
32484
32485
32486
32487
32488
32489
32490
32491
32492
32493
32494
32495
32496
32497
32498
32499
32500
32501
32502
32503
32504
32505
32506
32507
32508
32509
32510
32511
32512
32513
32514
32515
32516
32517
32518
32519
32520
32521
32522
32523
32524
32525
32526
32527
32528
32529
32530
32531
32532
32533
32534
32535
32536
32537
32538
32539
32540
32541
32542
32543
32544
32545
32546
32547
32548
32549
32550
32551
32552
32553
32554
32555
32556
32557
32558
32559
32560
32561
32562
32563
32564
32565
32566
32567
32568
32569
32570
32571
32572
32573
32574
32575
32576
32577
32578
32579
32580
32581
32582
32583
32584
32585
32586
32587
32588
32589
32590
32591
32592
32593
32594
32595
32596
32597
32598
32599
32600
32601
32602
32603
32604
32605
32606
32607
32608
32609
32610
32611
32612
32613
32614
32615
32616
32617
32618
32619
32620
32621
32622
32623
32624
32625
32626
32627
32628
32629
32630
32631
32632
32633
32634
32635
32636
32637
32638
32639
32640
32641
32642
32643
32644
32645
32646
32647
32648
32649
32650
32651
32652
32653
32654
32655
32656
32657
32658
32659
32660
32661
32662
32663
32664
32665
32666
32667
32668
32669
32670
32671
32672
32673
32674
32675
32676
32677
32678
32679
32680
32681
32682
32683
32684
32685
32686
32687
32688
32689
32690
32691
32692
32693
32694
32695
32696
32697
32698
32699
32700
32701
32702
32703
32704
32705
32706
32707
32708
32709
32710
32711
32712
32713
32714
32715
32716
32717
32718
32719
32720
32721
32722
32723
32724
32725
32726
32727
32728
32729
32730
32731
32732
32733
32734
32735
32736
32737
32738
32739
32740
32741
32742
32743
32744
32745
32746
32747
32748
32749
32750
32751
32752
32753
32754
32755
32756
32757
32758
32759
32760
32761
32762
32763
32764
32765
32766
32767
32768
32769
32770
32771
32772
32773
32774
32775
32776
32777
32778
32779
32780
32781
32782
32783
32784
32785
32786
32787
32788
32789
32790
32791
32792
32793
32794
32795
32796
32797
32798
32799
32800
32801
32802
32803
32804
32805
32806
32807
32808
32809
32810
32811
32812
32813
32814
32815
32816
32817
32818
32819
32820
32821
32822
32823
32824
32825
32826
32827
32828
32829
32830
32831
32832
32833
32834
32835
32836
32837
32838
32839
32840
32841
32842
32843
32844
32845
32846
32847
32848
32849
32850
32851
32852
32853
32854
32855
32856
32857
32858
32859
32860
32861
32862
32863
32864
32865
32866
32867
32868
32869
32870
32871
32872
32873
32874
32875
32876
32877
32878
32879
32880
32881
32882
32883
32884
32885
32886
32887
32888
32889
32890
32891
32892
32893
32894
32895
32896
32897
32898
32899
32900
32901
32902
32903
32904
32905
32906
32907
32908
32909
32910
32911
32912
32913
32914
32915
32916
32917
32918
32919
32920
32921
32922
32923
32924
32925
32926
32927
32928
32929
32930
32931
32932
32933
32934
32935
32936
32937
32938
32939
32940
32941
32942
32943
32944
32945
32946
32947
32948
32949
32950
32951
32952
32953
32954
32955
32956
32957
32958
32959
32960
32961
32962
32963
32964
32965
32966
32967
32968
32969
32970
32971
32972
32973
32974
32975
32976
32977
32978
32979
32980
32981
32982
32983
32984
32985
32986
32987
32988
32989
32990
32991
32992
32993
32994
32995
32996
32997
32998
32999
33000
33001
33002
33003
33004
33005
33006
33007
33008
33009
33010
33011
33012
33013
33014
33015
33016
33017
33018
33019
33020
33021
33022
33023
33024
33025
33026
33027
33028
33029
33030
33031
33032
33033
33034
33035
33036
33037
33038
33039
33040
33041
33042
33043
33044
33045
33046
33047
33048
33049
33050
33051
33052
33053
33054
33055
33056
33057
33058
33059
33060
33061
33062
33063
33064
33065
33066
33067
33068
33069
33070
33071
33072
33073
33074
33075
33076
33077
33078
33079
33080
33081
33082
33083
33084
33085
33086
33087
33088
33089
33090
33091
33092
33093
33094
33095
33096
33097
33098
33099
33100
33101
33102
33103
33104
33105
33106
33107
33108
33109
33110
33111
33112
33113
33114
33115
33116
33117
33118
33119
33120
33121
33122
33123
33124
33125
33126
33127
33128
33129
33130
33131
33132
33133
33134
33135
33136
33137
33138
33139
33140
33141
33142
33143
33144
33145
33146
33147
33148
33149
33150
33151
33152
33153
33154
33155
33156
33157
33158
33159
33160
33161
33162
33163
33164
33165
33166
33167
33168
33169
33170
33171
33172
33173
33174
33175
33176
33177
33178
33179
33180
33181
33182
33183
33184
33185
33186
33187
33188
33189
33190
33191
33192
33193
33194
33195
33196
33197
33198
33199
33200
33201
33202
33203
33204
33205
33206
33207
33208
33209
33210
33211
33212
33213
33214
33215
33216
33217
33218
33219
33220
33221
33222
33223
33224
33225
33226
33227
33228
33229
33230
33231
33232
33233
33234
33235
33236
33237
33238
33239
33240
33241
33242
33243
33244
33245
33246
33247
33248
33249
33250
33251
33252
33253
33254
33255
33256
33257
33258
33259
33260
33261
33262
33263
33264
33265
33266
33267
33268
33269
33270
33271
33272
33273
33274
33275
33276
33277
33278
33279
33280
33281
33282
33283
33284
33285
33286
33287
33288
33289
33290
33291
33292
33293
33294
33295
33296
33297
33298
33299
33300
33301
33302
33303
33304
33305
33306
33307
33308
33309
33310
33311
33312
33313
33314
33315
33316
33317
33318
33319
33320
33321
33322
33323
33324
33325
33326
33327
33328
33329
33330
33331
33332
33333
33334
33335
33336
33337
33338
33339
33340
33341
33342
33343
33344
33345
33346
33347
33348
33349
33350
33351
33352
33353
33354
33355
33356
33357
33358
33359
33360
33361
33362
33363
33364
33365
33366
33367
33368
33369
33370
33371
33372
33373
33374
33375
33376
33377
33378
33379
33380
33381
33382
33383
33384
33385
33386
33387
33388
33389
33390
33391
33392
33393
33394
33395
33396
33397
33398
33399
33400
33401
33402
33403
33404
33405
33406
33407
33408
33409
33410
33411
33412
33413
33414
33415
33416
33417
33418
33419
33420
33421
33422
33423
33424
33425
33426
33427
33428
33429
33430
33431
33432
33433
33434
33435
33436
33437
33438
33439
33440
33441
33442
33443
33444
33445
33446
33447
33448
33449
33450
33451
33452
33453
33454
33455
33456
33457
33458
33459
33460
33461
33462
33463
33464
33465
33466
33467
33468
33469
33470
33471
33472
33473
33474
33475
33476
33477
33478
33479
33480
33481
33482
33483
33484
33485
33486
33487
33488
33489
33490
33491
33492
33493
33494
33495
33496
33497
33498
33499
33500
33501
33502
33503
33504
33505
33506
33507
33508
33509
33510
33511
33512
33513
33514
33515
33516
33517
33518
33519
33520
33521
33522
33523
33524
33525
33526
33527
33528
33529
33530
33531
33532
33533
33534
33535
33536
33537
33538
33539
33540
33541
33542
33543
33544
33545
33546
33547
33548
33549
33550
33551
33552
33553
33554
33555
33556
33557
33558
33559
33560
33561
33562
33563
33564
33565
33566
33567
33568
33569
33570
33571
33572
33573
33574
33575
33576
33577
33578
33579
33580
33581
33582
33583
33584
33585
33586
33587
33588
33589
33590
33591
33592
33593
33594
33595
33596
33597
33598
33599
33600
33601
33602
33603
33604
33605
33606
33607
33608
33609
33610
33611
33612
33613
33614
33615
33616
33617
33618
33619
33620
33621
33622
33623
33624
33625
33626
33627
33628
33629
33630
33631
33632
33633
33634
33635
33636
33637
33638
33639
33640
33641
33642
33643
33644
33645
33646
33647
33648
33649
33650
33651
33652
33653
33654
33655
33656
33657
33658
33659
33660
33661
33662
33663
33664
33665
33666
33667
33668
33669
33670
33671
33672
33673
33674
33675
33676
33677
33678
33679
33680
33681
33682
33683
33684
33685
33686
33687
33688
33689
33690
33691
33692
33693
33694
33695
33696
33697
33698
33699
33700
33701
33702
33703
33704
33705
33706
33707
33708
33709
33710
33711
33712
33713
33714
33715
33716
33717
33718
33719
33720
33721
33722
33723
33724
33725
33726
33727
33728
33729
33730
33731
33732
33733
33734
33735
33736
33737
33738
33739
33740
33741
33742
33743
33744
33745
33746
33747
33748
33749
33750
33751
33752
33753
33754
33755
33756
33757
33758
33759
33760
33761
33762
33763
33764
33765
33766
33767
33768
33769
33770
33771
33772
33773
33774
33775
33776
33777
33778
33779
33780
33781
33782
33783
33784
33785
33786
33787
33788
33789
33790
33791
33792
33793
33794
33795
33796
33797
33798
33799
33800
33801
33802
33803
33804
33805
33806
33807
33808
33809
33810
33811
33812
33813
33814
33815
33816
33817
33818
33819
33820
33821
33822
33823
33824
33825
33826
33827
33828
33829
33830
33831
33832
33833
33834
33835
33836
33837
33838
33839
33840
33841
33842
33843
33844
33845
33846
33847
33848
33849
33850
33851
33852
33853
33854
33855
33856
33857
33858
33859
33860
33861
33862
33863
33864
33865
33866
33867
33868
33869
33870
33871
33872
33873
33874
33875
33876
33877
33878
33879
33880
33881
33882
33883
33884
33885
33886
33887
33888
33889
33890
33891
33892
33893
33894
33895
33896
33897
33898
33899
33900
33901
33902
33903
33904
33905
33906
33907
33908
33909
33910
33911
33912
33913
33914
33915
33916
33917
33918
33919
33920
33921
33922
33923
33924
33925
33926
33927
33928
33929
33930
33931
33932
33933
33934
33935
33936
33937
33938
33939
33940
33941
33942
33943
33944
33945
33946
33947
33948
33949
33950
33951
33952
33953
33954
33955
33956
33957
33958
33959
33960
33961
33962
33963
33964
33965
33966
33967
33968
33969
33970
33971
33972
33973
33974
33975
33976
33977
33978
33979
33980
33981
33982
33983
33984
33985
33986
33987
33988
33989
33990
33991
33992
33993
33994
33995
33996
33997
33998
33999
34000
34001
34002
34003
34004
34005
34006
34007
34008
34009
34010
34011
34012
34013
34014
34015
34016
34017
34018
34019
34020
34021
34022
34023
34024
34025
34026
34027
34028
34029
34030
34031
34032
34033
34034
34035
34036
34037
34038
34039
34040
34041
34042
34043
34044
34045
34046
34047
34048
34049
34050
34051
34052
34053
34054
34055
34056
34057
34058
34059
34060
34061
34062
34063
34064
34065
34066
34067
34068
34069
34070
34071
34072
34073
34074
34075
34076
34077
34078
34079
34080
34081
34082
34083
34084
34085
34086
34087
34088
34089
34090
34091
34092
34093
34094
34095
34096
34097
34098
34099
34100
34101
34102
34103
34104
34105
34106
34107
34108
34109
34110
34111
34112
34113
34114
34115
34116
34117
34118
34119
34120
34121
34122
34123
34124
34125
34126
34127
34128
34129
34130
34131
34132
34133
34134
34135
34136
34137
34138
34139
34140
34141
34142
34143
34144
34145
34146
34147
34148
34149
34150
34151
34152
34153
34154
34155
34156
34157
34158
34159
34160
34161
34162
34163
34164
34165
34166
34167
34168
34169
34170
34171
34172
34173
34174
34175
34176
34177
34178
34179
34180
34181
34182
34183
34184
34185
34186
34187
34188
34189
34190
34191
34192
34193
34194
34195
34196
34197
34198
34199
34200
34201
34202
34203
34204
34205
34206
34207
34208
34209
34210
34211
34212
34213
34214
34215
34216
34217
34218
34219
34220
34221
34222
34223
34224
34225
34226
34227
34228
34229
34230
34231
34232
34233
34234
34235
34236
34237
34238
34239
34240
34241
34242
34243
34244
34245
34246
34247
34248
34249
34250
34251
34252
34253
34254
34255
34256
34257
34258
34259
34260
34261
34262
34263
34264
34265
34266
34267
34268
34269
34270
34271
34272
34273
34274
34275
34276
34277
34278
34279
34280
34281
34282
34283
34284
34285
34286
34287
34288
34289
34290
34291
34292
34293
34294
34295
34296
34297
34298
34299
34300
34301
34302
34303
34304
34305
34306
34307
34308
34309
34310
34311
34312
34313
34314
34315
34316
34317
34318
34319
34320
34321
34322
34323
34324
34325
34326
34327
34328
34329
34330
34331
34332
34333
34334
34335
34336
34337
34338
34339
34340
34341
34342
34343
34344
34345
34346
34347
34348
34349
34350
34351
34352
34353
34354
34355
34356
34357
34358
34359
34360
34361
34362
34363
34364
34365
34366
34367
34368
34369
34370
34371
34372
34373
34374
34375
34376
34377
34378
34379
34380
34381
34382
34383
34384
34385
34386
34387
34388
34389
34390
34391
34392
34393
34394
34395
34396
34397
34398
34399
34400
34401
34402
34403
34404
34405
34406
34407
34408
34409
34410
34411
34412
34413
34414
34415
34416
34417
34418
34419
34420
34421
34422
34423
34424
34425
34426
34427
34428
34429
34430
34431
34432
34433
34434
34435
34436
34437
34438
34439
34440
34441
34442
34443
34444
34445
34446
34447
34448
34449
34450
34451
34452
34453
34454
34455
34456
34457
34458
34459
34460
34461
34462
34463
34464
34465
34466
34467
34468
34469
34470
34471
34472
34473
34474
34475
34476
34477
34478
34479
34480
34481
34482
34483
34484
34485
34486
34487
34488
34489
34490
34491
34492
34493
34494
34495
34496
34497
34498
34499
34500
34501
34502
34503
34504
34505
34506
34507
34508
34509
34510
34511
34512
34513
34514
34515
34516
34517
34518
34519
34520
34521
34522
34523
34524
34525
34526
34527
34528
34529
34530
34531
34532
34533
34534
34535
34536
34537
34538
34539
34540
34541
34542
34543
34544
34545
34546
34547
34548
34549
34550
34551
34552
34553
34554
34555
34556
34557
34558
34559
34560
34561
34562
34563
34564
34565
34566
34567
34568
34569
34570
34571
34572
34573
34574
34575
34576
34577
34578
34579
34580
34581
34582
34583
34584
34585
34586
34587
34588
34589
34590
34591
34592
34593
34594
34595
34596
34597
34598
34599
34600
34601
34602
34603
34604
34605
34606
34607
34608
34609
34610
34611
34612
34613
34614
34615
34616
34617
34618
34619
34620
34621
34622
34623
34624
34625
34626
34627
34628
34629
34630
34631
34632
34633
34634
34635
34636
34637
34638
34639
34640
34641
34642
34643
34644
34645
34646
34647
34648
34649
34650
34651
34652
34653
34654
34655
34656
34657
34658
34659
34660
34661
34662
34663
34664
34665
34666
34667
34668
34669
34670
34671
34672
34673
34674
34675
34676
34677
34678
34679
34680
34681
34682
34683
34684
34685
34686
34687
34688
34689
34690
34691
34692
34693
34694
34695
34696
34697
34698
34699
34700
34701
34702
34703
34704
34705
34706
34707
34708
34709
34710
34711
34712
34713
34714
34715
34716
34717
34718
34719
34720
34721
34722
34723
34724
34725
34726
34727
34728
34729
34730
34731
34732
34733
34734
34735
34736
34737
34738
34739
34740
34741
34742
34743
34744
34745
34746
34747
34748
34749
34750
34751
34752
34753
34754
34755
34756
34757
34758
34759
34760
34761
34762
34763
34764
34765
34766
34767
34768
34769
34770
34771
34772
34773
34774
34775
34776
34777
34778
34779
34780
34781
34782
34783
34784
34785
34786
34787
34788
34789
34790
34791
34792
34793
34794
34795
34796
34797
34798
34799
34800
34801
34802
34803
34804
34805
34806
34807
34808
34809
34810
34811
34812
34813
34814
34815
34816
34817
34818
34819
34820
34821
34822
34823
34824
34825
34826
34827
34828
34829
34830
34831
34832
34833
34834
34835
34836
34837
34838
34839
34840
34841
34842
34843
34844
34845
34846
34847
34848
34849
34850
34851
34852
34853
34854
34855
34856
34857
34858
34859
34860
34861
34862
34863
34864
34865
34866
34867
34868
34869
34870
34871
34872
34873
34874
34875
34876
34877
34878
34879
34880
34881
34882
34883
34884
34885
34886
34887
34888
34889
34890
34891
34892
34893
34894
34895
34896
34897
34898
34899
34900
34901
34902
34903
34904
34905
34906
34907
34908
34909
34910
34911
34912
34913
34914
34915
34916
34917
34918
34919
34920
34921
34922
34923
34924
34925
34926
34927
34928
34929
34930
34931
34932
34933
34934
34935
34936
34937
34938
34939
34940
34941
34942
34943
34944
34945
34946
34947
34948
34949
34950
34951
34952
34953
34954
34955
34956
34957
34958
34959
34960
34961
34962
34963
34964
34965
34966
34967
34968
34969
34970
34971
34972
34973
34974
34975
34976
34977
34978
34979
34980
34981
34982
34983
34984
34985
34986
34987
34988
34989
34990
34991
34992
34993
34994
34995
34996
34997
34998
34999
35000
35001
35002
35003
35004
35005
35006
35007
35008
35009
35010
35011
35012
35013
35014
35015
35016
35017
35018
35019
35020
35021
35022
35023
35024
35025
35026
35027
35028
35029
35030
35031
35032
35033
35034
35035
35036
35037
35038
35039
35040
35041
35042
35043
35044
35045
35046
35047
35048
35049
35050
35051
35052
35053
35054
35055
35056
35057
35058
35059
35060
35061
35062
35063
35064
35065
35066
35067
35068
35069
35070
35071
35072
35073
35074
35075
35076
35077
35078
35079
35080
35081
35082
35083
35084
35085
35086
35087
35088
35089
35090
35091
35092
35093
35094
35095
35096
35097
35098
35099
35100
35101
35102
35103
35104
35105
35106
35107
35108
35109
35110
35111
35112
35113
35114
35115
35116
35117
35118
35119
35120
35121
35122
35123
35124
35125
35126
35127
35128
35129
35130
35131
35132
35133
35134
35135
35136
35137
35138
35139
35140
35141
35142
35143
35144
35145
35146
35147
35148
35149
35150
35151
35152
35153
35154
35155
35156
35157
35158
35159
35160
35161
35162
35163
35164
35165
35166
35167
35168
35169
35170
35171
35172
35173
35174
35175
35176
35177
35178
35179
35180
35181
35182
35183
35184
35185
35186
35187
35188
35189
35190
35191
35192
35193
35194
35195
35196
35197
35198
35199
35200
35201
35202
35203
35204
35205
35206
35207
35208
35209
35210
35211
35212
35213
35214
35215
35216
35217
35218
35219
35220
35221
35222
35223
35224
35225
35226
35227
35228
35229
35230
35231
35232
35233
35234
35235
35236
35237
35238
35239
35240
35241
35242
35243
35244
35245
35246
35247
35248
35249
35250
35251
35252
35253
35254
35255
35256
35257
35258
35259
35260
35261
35262
35263
35264
35265
35266
35267
35268
35269
35270
35271
35272
35273
35274
35275
35276
35277
35278
35279
35280
35281
35282
35283
35284
35285
35286
35287
35288
35289
35290
35291
35292
35293
35294
35295
35296
35297
35298
35299
35300
35301
35302
35303
35304
35305
35306
35307
35308
35309
35310
35311
35312
35313
35314
35315
35316
35317
35318
35319
35320
35321
35322
35323
35324
35325
35326
35327
35328
35329
35330
35331
35332
35333
35334
35335
35336
35337
35338
35339
35340
35341
35342
35343
35344
35345
35346
35347
35348
35349
35350
35351
35352
35353
35354
35355
35356
35357
35358
35359
35360
35361
35362
35363
35364
35365
35366
35367
35368
35369
35370
35371
35372
35373
35374
35375
35376
35377
35378
35379
35380
35381
35382
35383
35384
35385
35386
35387
35388
35389
35390
35391
35392
35393
35394
35395
35396
35397
35398
35399
35400
35401
35402
35403
35404
35405
35406
35407
35408
35409
35410
35411
35412
35413
35414
35415
35416
35417
35418
35419
35420
35421
35422
35423
35424
35425
35426
35427
35428
35429
35430
35431
35432
35433
35434
35435
35436
35437
35438
35439
35440
35441
35442
35443
35444
35445
35446
35447
35448
35449
35450
35451
35452
35453
35454
35455
35456
35457
35458
35459
35460
35461
35462
35463
35464
35465
35466
35467
35468
35469
35470
35471
35472
35473
35474
35475
35476
35477
35478
35479
35480
35481
35482
35483
35484
35485
35486
35487
35488
35489
35490
35491
35492
35493
35494
35495
35496
35497
35498
35499
35500
35501
35502
35503
35504
35505
35506
35507
35508
35509
35510
35511
35512
35513
35514
35515
35516
35517
35518
35519
35520
35521
35522
35523
35524
35525
35526
35527
35528
35529
35530
35531
35532
35533
35534
35535
35536
35537
35538
35539
35540
35541
35542
35543
35544
35545
35546
35547
35548
35549
35550
35551
35552
35553
35554
35555
35556
35557
35558
35559
35560
35561
35562
35563
35564
35565
35566
35567
35568
35569
35570
35571
35572
35573
35574
35575
35576
35577
35578
35579
35580
35581
35582
35583
35584
35585
35586
35587
35588
35589
35590
35591
35592
35593
35594
35595
35596
35597
35598
35599
35600
35601
35602
35603
35604
35605
35606
35607
35608
35609
35610
35611
35612
35613
35614
35615
35616
35617
35618
35619
35620
35621
35622
35623
35624
35625
35626
35627
35628
35629
35630
35631
35632
35633
35634
35635
35636
35637
35638
35639
35640
35641
35642
35643
35644
35645
35646
35647
35648
35649
35650
35651
35652
35653
35654
35655
35656
35657
35658
35659
35660
35661
35662
35663
35664
35665
35666
35667
35668
35669
35670
35671
35672
35673
35674
35675
35676
35677
35678
35679
35680
35681
35682
35683
35684
35685
35686
35687
35688
35689
35690
35691
35692
35693
35694
35695
35696
35697
35698
35699
35700
35701
35702
35703
35704
35705
35706
35707
35708
35709
35710
35711
35712
35713
35714
35715
35716
35717
35718
35719
35720
35721
35722
35723
35724
35725
35726
35727
35728
35729
35730
35731
35732
35733
35734
35735
35736
35737
35738
35739
35740
35741
35742
35743
35744
35745
35746
35747
35748
35749
35750
35751
35752
35753
35754
35755
35756
35757
35758
35759
35760
35761
35762
35763
35764
35765
35766
35767
35768
35769
35770
35771
35772
35773
35774
35775
35776
35777
35778
35779
35780
35781
35782
35783
35784
35785
35786
35787
35788
35789
35790
35791
35792
35793
35794
35795
35796
35797
35798
35799
35800
35801
35802
35803
35804
35805
35806
35807
35808
35809
35810
35811
35812
35813
35814
35815
35816
35817
35818
35819
35820
35821
35822
35823
35824
35825
35826
35827
35828
35829
35830
35831
35832
35833
35834
35835
35836
35837
35838
35839
35840
35841
35842
35843
35844
35845
35846
35847
35848
35849
35850
35851
35852
35853
35854
35855
35856
35857
35858
35859
35860
35861
35862
35863
35864
35865
35866
35867
35868
35869
35870
35871
35872
35873
35874
35875
35876
35877
35878
35879
35880
35881
35882
35883
35884
35885
35886
35887
35888
35889
35890
35891
35892
35893
35894
35895
35896
35897
35898
35899
35900
35901
35902
35903
35904
35905
35906
35907
35908
35909
35910
35911
35912
35913
35914
35915
35916
35917
35918
35919
35920
35921
35922
35923
35924
35925
35926
35927
35928
35929
35930
35931
35932
35933
35934
35935
35936
35937
35938
35939
35940
35941
35942
35943
35944
35945
35946
35947
35948
35949
35950
35951
35952
35953
35954
35955
35956
35957
35958
35959
35960
35961
35962
35963
35964
35965
35966
35967
35968
35969
35970
35971
35972
35973
35974
35975
35976
35977
35978
35979
35980
35981
35982
35983
35984
35985
35986
35987
35988
35989
35990
35991
35992
35993
35994
35995
35996
35997
35998
35999
36000
36001
36002
36003
36004
36005
36006
36007
36008
36009
36010
36011
36012
36013
36014
36015
36016
36017
36018
36019
36020
36021
36022
36023
36024
36025
36026
36027
36028
36029
36030
36031
36032
36033
36034
36035
36036
36037
36038
36039
36040
36041
36042
36043
36044
36045
36046
36047
36048
36049
36050
36051
36052
36053
36054
36055
36056
36057
36058
36059
36060
36061
36062
36063
36064
36065
36066
36067
36068
36069
36070
36071
36072
36073
36074
36075
36076
36077
36078
36079
36080
36081
36082
36083
36084
36085
36086
36087
36088
36089
36090
36091
36092
36093
36094
36095
36096
36097
36098
36099
36100
36101
36102
36103
36104
36105
36106
36107
36108
36109
36110
36111
36112
36113
36114
36115
36116
36117
36118
36119
36120
36121
36122
36123
36124
36125
36126
36127
36128
36129
36130
36131
36132
36133
36134
36135
36136
36137
36138
36139
36140
36141
36142
36143
36144
36145
36146
36147
36148
36149
36150
36151
36152
36153
36154
36155
36156
36157
36158
36159
36160
36161
36162
36163
36164
36165
36166
36167
36168
36169
36170
36171
36172
36173
36174
36175
36176
36177
36178
36179
36180
36181
36182
36183
36184
36185
36186
36187
36188
36189
36190
36191
36192
36193
36194
36195
36196
36197
36198
36199
36200
36201
36202
36203
36204
36205
36206
36207
36208
36209
36210
36211
36212
36213
36214
36215
36216
36217
36218
36219
36220
36221
36222
36223
36224
36225
36226
36227
36228
36229
36230
36231
36232
36233
36234
36235
36236
36237
36238
36239
36240
36241
36242
36243
36244
36245
36246
36247
36248
36249
36250
36251
36252
36253
36254
36255
36256
36257
36258
36259
36260
36261
36262
36263
36264
36265
36266
36267
36268
36269
36270
36271
36272
36273
36274
36275
36276
36277
36278
36279
36280
36281
36282
36283
36284
36285
36286
36287
36288
36289
36290
36291
36292
36293
36294
36295
36296
36297
36298
36299
36300
36301
36302
36303
36304
36305
36306
36307
36308
36309
36310
36311
36312
36313
36314
36315
36316
36317
36318
36319
36320
36321
36322
36323
36324
36325
36326
36327
36328
36329
36330
36331
36332
36333
36334
36335
36336
36337
36338
36339
36340
36341
36342
36343
36344
36345
36346
36347
36348
36349
36350
36351
36352
36353
36354
36355
36356
36357
36358
36359
36360
36361
36362
36363
36364
36365
36366
36367
36368
36369
36370
36371
36372
36373
36374
36375
36376
36377
36378
36379
36380
36381
36382
36383
36384
36385
36386
36387
36388
36389
36390
36391
36392
36393
36394
36395
36396
36397
36398
36399
36400
36401
36402
36403
36404
36405
36406
36407
36408
36409
36410
36411
36412
36413
36414
36415
36416
36417
36418
36419
36420
36421
36422
36423
36424
36425
36426
36427
36428
36429
36430
36431
36432
36433
36434
36435
36436
36437
36438
36439
36440
36441
36442
36443
36444
36445
36446
36447
36448
36449
36450
36451
36452
36453
36454
36455
36456
36457
36458
36459
36460
36461
36462
36463
36464
36465
36466
36467
36468
36469
36470
36471
36472
36473
36474
36475
36476
36477
36478
36479
36480
36481
36482
36483
36484
36485
36486
36487
36488
36489
36490
36491
36492
36493
36494
36495
36496
36497
36498
36499
36500
36501
36502
36503
36504
36505
36506
36507
36508
36509
36510
36511
36512
36513
36514
36515
36516
36517
36518
36519
36520
36521
36522
36523
36524
36525
36526
36527
36528
36529
36530
36531
36532
36533
36534
36535
36536
36537
36538
36539
36540
36541
36542
36543
36544
36545
36546
36547
36548
36549
36550
36551
36552
36553
36554
36555
36556
36557
36558
36559
36560
36561
36562
36563
36564
36565
36566
36567
36568
36569
36570
36571
36572
36573
36574
36575
36576
36577
36578
36579
36580
36581
36582
36583
36584
36585
36586
36587
36588
36589
36590
36591
36592
36593
36594
36595
36596
36597
36598
36599
36600
36601
36602
36603
36604
36605
36606
36607
36608
36609
36610
36611
36612
36613
36614
36615
36616
36617
36618
36619
36620
36621
36622
36623
36624
36625
36626
36627
36628
36629
36630
36631
36632
36633
36634
36635
36636
36637
36638
36639
36640
36641
36642
36643
36644
36645
36646
36647
36648
36649
36650
36651
36652
36653
36654
36655
36656
36657
36658
36659
36660
36661
36662
36663
36664
36665
36666
36667
36668
36669
36670
36671
36672
36673
36674
36675
36676
36677
36678
36679
36680
36681
36682
36683
36684
36685
36686
36687
36688
36689
36690
36691
36692
36693
36694
36695
36696
36697
36698
36699
36700
36701
36702
36703
36704
36705
36706
36707
36708
36709
36710
36711
36712
36713
36714
36715
36716
36717
36718
36719
36720
36721
36722
36723
36724
36725
36726
36727
36728
36729
36730
36731
36732
36733
36734
36735
36736
36737
36738
36739
36740
36741
36742
36743
36744
36745
36746
36747
36748
36749
36750
36751
36752
36753
36754
36755
36756
36757
36758
36759
36760
36761
36762
36763
36764
36765
36766
36767
36768
36769
36770
36771
36772
36773
36774
36775
36776
36777
36778
36779
36780
36781
36782
36783
36784
36785
36786
36787
36788
36789
36790
36791
36792
36793
36794
36795
36796
36797
36798
36799
36800
36801
36802
36803
36804
36805
36806
36807
36808
36809
36810
36811
36812
36813
36814
36815
36816
36817
36818
36819
36820
36821
36822
36823
36824
36825
36826
36827
36828
36829
36830
36831
36832
36833
36834
36835
36836
36837
36838
36839
36840
36841
36842
36843
36844
36845
36846
36847
36848
36849
36850
36851
36852
36853
36854
36855
36856
36857
36858
36859
36860
36861
36862
36863
36864
36865
36866
36867
36868
36869
36870
36871
36872
36873
36874
36875
36876
36877
36878
36879
36880
36881
36882
36883
36884
36885
36886
36887
36888
36889
36890
36891
36892
36893
36894
36895
36896
36897
36898
36899
36900
36901
36902
36903
36904
36905
36906
36907
36908
36909
36910
36911
36912
36913
36914
36915
36916
36917
36918
36919
36920
36921
36922
36923
36924
36925
36926
36927
36928
36929
36930
36931
36932
36933
36934
36935
36936
36937
36938
36939
36940
36941
36942
36943
36944
36945
36946
36947
36948
36949
36950
36951
36952
36953
36954
36955
36956
36957
36958
36959
36960
36961
36962
36963
36964
36965
36966
36967
36968
36969
36970
36971
36972
36973
36974
36975
36976
36977
36978
36979
36980
36981
36982
36983
36984
36985
36986
36987
36988
36989
36990
36991
36992
36993
36994
36995
36996
36997
36998
36999
37000
37001
37002
37003
37004
37005
37006
37007
37008
37009
37010
37011
37012
37013
37014
37015
37016
37017
37018
37019
37020
37021
37022
37023
37024
37025
37026
37027
37028
37029
37030
37031
37032
37033
37034
37035
37036
37037
37038
37039
37040
37041
37042
37043
37044
37045
37046
37047
37048
37049
37050
37051
37052
37053
37054
37055
37056
37057
37058
37059
37060
37061
37062
37063
37064
37065
37066
37067
37068
37069
37070
37071
37072
37073
37074
37075
37076
37077
37078
37079
37080
37081
37082
37083
37084
37085
37086
37087
37088
37089
37090
37091
37092
37093
37094
37095
37096
37097
37098
37099
37100
37101
37102
37103
37104
37105
37106
37107
37108
37109
37110
37111
37112
37113
37114
37115
37116
37117
37118
37119
37120
37121
37122
37123
37124
37125
37126
37127
37128
37129
37130
37131
37132
37133
37134
37135
37136
37137
37138
37139
37140
37141
37142
37143
37144
37145
37146
37147
37148
37149
37150
37151
37152
37153
37154
37155
37156
37157
37158
37159
37160
37161
37162
37163
37164
37165
37166
37167
37168
37169
37170
37171
37172
37173
37174
37175
37176
37177
37178
37179
37180
37181
37182
37183
37184
37185
37186
37187
37188
37189
37190
37191
37192
37193
37194
37195
37196
37197
37198
37199
37200
37201
37202
37203
37204
37205
37206
37207
37208
37209
37210
37211
37212
37213
37214
37215
37216
37217
37218
37219
37220
37221
37222
37223
37224
37225
37226
37227
37228
37229
37230
37231
37232
37233
37234
37235
37236
37237
37238
37239
37240
37241
37242
37243
37244
37245
37246
37247
37248
37249
37250
37251
37252
37253
37254
37255
37256
37257
37258
37259
37260
37261
37262
37263
37264
37265
37266
37267
37268
37269
37270
37271
37272
37273
37274
37275
37276
37277
37278
37279
37280
37281
37282
37283
37284
37285
37286
37287
37288
37289
37290
37291
37292
37293
37294
37295
37296
37297
37298
37299
37300
37301
37302
37303
37304
37305
37306
37307
37308
37309
37310
37311
37312
37313
37314
37315
37316
37317
37318
37319
37320
37321
37322
37323
37324
37325
37326
37327
37328
37329
37330
37331
37332
37333
37334
37335
37336
37337
37338
37339
37340
37341
37342
37343
37344
37345
37346
37347
37348
37349
37350
37351
37352
37353
37354
37355
37356
37357
37358
37359
37360
37361
37362
37363
37364
37365
37366
37367
37368
37369
37370
37371
37372
37373
37374
37375
37376
37377
37378
37379
37380
37381
37382
37383
37384
37385
37386
37387
37388
37389
37390
37391
37392
37393
37394
37395
37396
37397
37398
37399
37400
37401
37402
37403
37404
37405
37406
37407
37408
37409
37410
37411
37412
37413
37414
37415
37416
37417
37418
37419
37420
37421
37422
37423
37424
37425
37426
37427
37428
37429
37430
37431
37432
37433
37434
37435
37436
37437
37438
37439
37440
37441
37442
37443
37444
37445
37446
37447
37448
37449
37450
37451
37452
37453
37454
37455
37456
37457
37458
37459
37460
37461
37462
37463
37464
37465
37466
37467
37468
37469
37470
37471
37472
37473
37474
37475
37476
37477
37478
37479
37480
37481
37482
37483
37484
37485
37486
37487
37488
37489
37490
37491
37492
37493
37494
37495
37496
37497
37498
37499
37500
37501
37502
37503
37504
37505
37506
37507
37508
37509
37510
37511
37512
37513
37514
37515
37516
37517
37518
37519
37520
37521
37522
37523
37524
37525
37526
37527
37528
37529
37530
37531
37532
37533
37534
37535
37536
37537
37538
37539
37540
37541
37542
37543
37544
37545
37546
37547
37548
37549
37550
37551
37552
37553
37554
37555
37556
37557
37558
37559
37560
37561
37562
37563
37564
37565
37566
37567
37568
37569
37570
37571
37572
37573
37574
37575
37576
37577
37578
37579
37580
37581
37582
37583
37584
37585
37586
37587
37588
37589
37590
37591
37592
37593
37594
37595
37596
37597
37598
37599
37600
37601
37602
37603
37604
37605
37606
37607
37608
37609
37610
37611
37612
37613
37614
37615
37616
37617
37618
37619
37620
37621
37622
37623
37624
37625
37626
37627
37628
37629
37630
37631
37632
37633
37634
37635
37636
37637
37638
37639
37640
37641
37642
37643
37644
37645
37646
37647
37648
37649
37650
37651
37652
37653
37654
37655
37656
37657
37658
37659
37660
37661
37662
37663
37664
37665
37666
37667
37668
37669
37670
37671
37672
37673
37674
37675
37676
37677
37678
37679
37680
37681
37682
37683
37684
37685
37686
37687
37688
37689
37690
37691
37692
37693
37694
37695
37696
37697
37698
37699
37700
37701
37702
37703
37704
37705
37706
37707
37708
37709
37710
37711
37712
37713
37714
37715
37716
37717
37718
37719
37720
37721
37722
37723
37724
37725
37726
37727
37728
37729
37730
37731
37732
37733
37734
37735
37736
37737
37738
37739
37740
37741
37742
37743
37744
37745
37746
37747
37748
37749
37750
37751
37752
37753
37754
37755
37756
37757
37758
37759
37760
37761
37762
37763
37764
37765
37766
37767
37768
37769
37770
37771
37772
37773
37774
37775
37776
37777
37778
37779
37780
37781
37782
37783
37784
37785
37786
37787
37788
37789
37790
37791
37792
37793
37794
37795
37796
37797
37798
37799
37800
37801
37802
37803
37804
37805
37806
37807
37808
37809
37810
37811
37812
37813
37814
37815
37816
37817
37818
37819
37820
37821
37822
37823
37824
37825
37826
37827
37828
37829
37830
37831
37832
37833
37834
37835
37836
37837
37838
37839
37840
37841
37842
37843
37844
37845
37846
37847
37848
37849
37850
37851
37852
37853
37854
37855
37856
37857
37858
37859
37860
37861
37862
37863
37864
37865
37866
37867
37868
37869
37870
37871
37872
37873
37874
37875
37876
37877
37878
37879
37880
37881
37882
37883
37884
37885
37886
37887
37888
37889
37890
37891
37892
37893
37894
37895
37896
37897
37898
37899
37900
37901
37902
37903
37904
37905
37906
37907
37908
37909
37910
37911
37912
37913
37914
37915
37916
37917
37918
37919
37920
37921
37922
37923
37924
37925
37926
37927
37928
37929
37930
37931
37932
37933
37934
37935
37936
37937
37938
37939
37940
37941
37942
37943
37944
37945
37946
37947
37948
37949
37950
37951
37952
37953
37954
37955
37956
37957
37958
37959
37960
37961
37962
37963
37964
37965
37966
37967
37968
37969
37970
37971
37972
37973
37974
37975
37976
37977
37978
37979
37980
37981
37982
37983
37984
37985
37986
37987
37988
37989
37990
37991
37992
37993
37994
37995
37996
37997
37998
37999
38000
38001
38002
38003
38004
38005
38006
38007
38008
38009
38010
38011
38012
38013
38014
38015
38016
38017
38018
38019
38020
38021
38022
38023
38024
38025
38026
38027
38028
38029
38030
38031
38032
38033
38034
38035
38036
38037
38038
38039
38040
38041
38042
38043
38044
38045
38046
38047
38048
38049
38050
38051
38052
38053
38054
38055
38056
38057
38058
38059
38060
38061
38062
38063
38064
38065
38066
38067
38068
38069
38070
38071
38072
38073
38074
38075
38076
38077
38078
38079
38080
38081
38082
38083
38084
38085
38086
38087
38088
38089
38090
38091
38092
38093
38094
38095
38096
38097
38098
38099
38100
38101
38102
38103
38104
38105
38106
38107
38108
38109
38110
38111
38112
38113
38114
38115
38116
38117
38118
38119
38120
38121
38122
38123
38124
38125
38126
38127
38128
38129
38130
38131
38132
38133
38134
38135
38136
38137
38138
38139
38140
38141
38142
38143
38144
38145
38146
38147
38148
38149
38150
38151
38152
38153
38154
38155
38156
38157
38158
38159
38160
38161
38162
38163
38164
38165
38166
38167
38168
38169
38170
38171
38172
38173
38174
38175
38176
38177
38178
38179
38180
38181
38182
38183
38184
38185
38186
38187
38188
38189
38190
38191
38192
38193
38194
38195
38196
38197
38198
38199
38200
38201
38202
38203
38204
38205
38206
38207
38208
38209
38210
38211
38212
38213
38214
38215
38216
38217
38218
38219
38220
38221
38222
38223
38224
38225
38226
38227
38228
38229
38230
38231
38232
38233
38234
38235
38236
38237
38238
38239
38240
38241
38242
38243
38244
38245
38246
38247
38248
38249
38250
38251
38252
38253
38254
38255
38256
38257
38258
38259
38260
38261
38262
38263
38264
38265
38266
38267
38268
38269
38270
38271
38272
38273
38274
38275
38276
38277
38278
38279
38280
38281
38282
38283
38284
38285
38286
38287
38288
38289
38290
38291
38292
38293
38294
38295
38296
38297
38298
38299
38300
38301
38302
38303
38304
38305
38306
38307
38308
38309
38310
38311
38312
38313
38314
38315
38316
38317
38318
38319
38320
38321
38322
38323
38324
38325
38326
38327
38328
38329
38330
38331
38332
38333
38334
38335
38336
38337
38338
38339
38340
38341
38342
38343
38344
38345
38346
38347
38348
38349
38350
38351
38352
38353
38354
38355
38356
38357
38358
38359
38360
38361
38362
38363
38364
38365
38366
38367
38368
38369
38370
38371
38372
38373
38374
38375
38376
38377
38378
38379
38380
38381
38382
38383
38384
38385
38386
38387
38388
38389
38390
38391
38392
38393
38394
38395
38396
38397
38398
38399
38400
38401
38402
38403
38404
38405
38406
38407
38408
38409
38410
38411
38412
38413
38414
38415
38416
38417
38418
38419
38420
38421
38422
38423
38424
38425
38426
38427
38428
38429
38430
38431
38432
38433
38434
38435
38436
38437
38438
38439
38440
38441
38442
38443
38444
38445
38446
38447
38448
38449
38450
38451
38452
38453
38454
38455
38456
38457
38458
38459
38460
38461
38462
38463
38464
38465
38466
38467
38468
38469
38470
38471
38472
38473
38474
38475
38476
38477
38478
38479
38480
38481
38482
38483
38484
38485
38486
38487
38488
38489
38490
38491
38492
38493
38494
38495
38496
38497
38498
38499
38500
38501
38502
38503
38504
38505
38506
38507
38508
38509
38510
38511
38512
38513
38514
38515
38516
38517
38518
38519
38520
38521
38522
38523
38524
38525
38526
38527
38528
38529
38530
38531
38532
38533
38534
38535
38536
38537
38538
38539
38540
38541
38542
38543
38544
38545
38546
38547
38548
38549
38550
38551
38552
38553
38554
38555
38556
38557
38558
38559
38560
38561
38562
38563
38564
38565
38566
38567
38568
38569
38570
38571
38572
38573
38574
38575
38576
38577
38578
38579
38580
38581
38582
38583
38584
38585
38586
38587
38588
38589
38590
38591
38592
38593
38594
38595
38596
38597
38598
38599
38600
38601
38602
38603
38604
38605
38606
38607
38608
38609
38610
38611
38612
38613
38614
38615
38616
38617
38618
38619
38620
38621
38622
38623
38624
38625
38626
38627
38628
38629
38630
38631
38632
38633
38634
38635
38636
38637
38638
38639
38640
38641
38642
38643
38644
38645
38646
38647
38648
38649
38650
38651
38652
38653
38654
38655
38656
38657
38658
38659
38660
38661
38662
38663
38664
38665
38666
38667
38668
38669
38670
38671
38672
38673
38674
38675
38676
38677
38678
38679
38680
38681
38682
38683
38684
38685
38686
38687
38688
38689
38690
38691
38692
38693
38694
38695
38696
38697
38698
38699
38700
38701
38702
38703
38704
38705
38706
38707
38708
38709
38710
38711
38712
38713
38714
38715
38716
38717
38718
38719
38720
38721
38722
38723
38724
38725
38726
38727
38728
38729
38730
38731
38732
38733
38734
38735
38736
38737
38738
38739
38740
38741
38742
38743
38744
38745
38746
38747
38748
38749
38750
38751
38752
38753
38754
38755
38756
38757
38758
38759
38760
38761
38762
38763
38764
38765
38766
38767
38768
38769
38770
38771
38772
38773
38774
38775
38776
38777
38778
38779
38780
38781
38782
38783
38784
38785
38786
38787
38788
38789
38790
38791
38792
38793
38794
38795
38796
38797
38798
38799
38800
38801
38802
38803
38804
38805
38806
38807
38808
38809
38810
38811
38812
38813
38814
38815
38816
38817
38818
38819
38820
38821
38822
38823
38824
38825
38826
38827
38828
38829
38830
38831
38832
38833
38834
38835
38836
38837
38838
38839
38840
38841
38842
38843
38844
38845
38846
38847
38848
38849
38850
38851
38852
38853
38854
38855
38856
38857
38858
38859
38860
38861
38862
38863
38864
38865
38866
38867
38868
38869
38870
38871
38872
38873
38874
38875
38876
38877
38878
38879
38880
38881
38882
38883
38884
38885
38886
38887
38888
38889
38890
38891
38892
38893
38894
38895
38896
38897
38898
38899
38900
38901
38902
38903
38904
38905
38906
38907
38908
38909
38910
38911
38912
38913
38914
38915
38916
38917
38918
38919
38920
38921
38922
38923
38924
38925
38926
38927
38928
38929
38930
38931
38932
38933
38934
38935
38936
38937
38938
38939
38940
38941
38942
38943
38944
38945
38946
38947
38948
38949
38950
38951
38952
38953
38954
38955
38956
38957
38958
38959
38960
38961
38962
38963
38964
38965
38966
38967
38968
38969
38970
38971
38972
38973
38974
38975
38976
38977
38978
38979
38980
38981
38982
38983
38984
38985
38986
38987
38988
38989
38990
38991
38992
38993
38994
38995
38996
38997
38998
38999
39000
39001
39002
39003
39004
39005
39006
39007
39008
39009
39010
39011
39012
39013
39014
39015
39016
39017
39018
39019
39020
39021
39022
39023
39024
39025
39026
39027
39028
39029
39030
39031
39032
39033
39034
39035
39036
39037
39038
39039
39040
39041
39042
39043
39044
39045
39046
39047
39048
39049
39050
39051
39052
39053
39054
39055
39056
39057
39058
39059
39060
39061
39062
39063
39064
39065
39066
39067
39068
39069
39070
39071
39072
39073
39074
39075
39076
39077
39078
39079
39080
39081
39082
39083
39084
39085
39086
39087
39088
39089
39090
39091
39092
39093
39094
39095
39096
39097
39098
39099
39100
39101
39102
39103
39104
39105
39106
39107
39108
39109
39110
39111
39112
39113
39114
39115
39116
39117
39118
39119
39120
39121
39122
39123
39124
39125
39126
39127
39128
39129
39130
39131
39132
39133
39134
39135
39136
39137
39138
39139
39140
39141
39142
39143
39144
39145
39146
39147
39148
39149
39150
39151
39152
39153
39154
39155
39156
39157
39158
39159
39160
39161
39162
39163
39164
39165
39166
39167
39168
39169
39170
39171
39172
39173
39174
39175
39176
39177
39178
39179
39180
39181
39182
39183
39184
39185
39186
39187
39188
39189
39190
39191
39192
39193
39194
39195
39196
39197
39198
39199
39200
39201
39202
39203
39204
39205
39206
39207
39208
39209
39210
39211
39212
39213
39214
39215
39216
39217
39218
39219
39220
39221
39222
39223
39224
39225
39226
39227
39228
39229
39230
39231
39232
39233
39234
39235
39236
39237
39238
39239
39240
39241
39242
39243
39244
39245
39246
39247
39248
39249
39250
39251
39252
39253
39254
39255
39256
39257
39258
39259
39260
39261
39262
39263
39264
39265
39266
39267
39268
39269
39270
39271
39272
39273
39274
39275
39276
39277
39278
39279
39280
39281
39282
39283
39284
39285
39286
39287
39288
39289
39290
39291
39292
39293
39294
39295
39296
39297
39298
39299
39300
39301
39302
39303
39304
39305
39306
39307
39308
39309
39310
39311
39312
39313
39314
39315
39316
39317
39318
39319
39320
39321
39322
39323
39324
39325
39326
39327
39328
39329
39330
39331
39332
39333
39334
39335
39336
39337
39338
39339
39340
39341
39342
39343
39344
39345
39346
39347
39348
39349
39350
39351
39352
39353
39354
39355
39356
39357
39358
39359
39360
39361
39362
39363
39364
39365
39366
39367
39368
39369
39370
39371
39372
39373
39374
39375
39376
39377
39378
39379
39380
39381
39382
39383
39384
39385
39386
39387
39388
39389
39390
39391
39392
39393
39394
39395
39396
39397
39398
39399
39400
39401
39402
39403
39404
39405
39406
39407
39408
39409
39410
39411
39412
39413
39414
39415
39416
39417
39418
39419
39420
39421
39422
39423
39424
39425
39426
39427
39428
39429
39430
39431
39432
39433
39434
39435
39436
39437
39438
39439
39440
39441
39442
39443
39444
39445
39446
39447
39448
39449
39450
39451
39452
39453
39454
39455
39456
39457
39458
39459
39460
39461
39462
39463
39464
39465
39466
39467
39468
39469
39470
39471
39472
39473
39474
39475
39476
39477
39478
39479
39480
39481
39482
39483
39484
39485
39486
39487
39488
39489
39490
39491
39492
39493
39494
39495
39496
39497
39498
39499
39500
39501
39502
39503
39504
39505
39506
39507
39508
39509
39510
39511
39512
39513
39514
39515
39516
39517
39518
39519
39520
39521
39522
39523
39524
39525
39526
39527
39528
39529
39530
39531
39532
39533
39534
39535
39536
39537
39538
39539
39540
39541
39542
39543
39544
39545
39546
39547
39548
39549
39550
39551
39552
39553
39554
39555
39556
39557
39558
39559
39560
39561
39562
39563
39564
39565
39566
39567
39568
39569
39570
39571
39572
39573
39574
39575
39576
39577
39578
39579
39580
39581
39582
39583
39584
39585
39586
39587
39588
39589
39590
39591
39592
39593
39594
39595
39596
39597
39598
39599
39600
39601
39602
39603
39604
39605
39606
39607
39608
39609
39610
39611
39612
39613
39614
39615
39616
39617
39618
39619
39620
39621
39622
39623
39624
39625
39626
39627
39628
39629
39630
39631
39632
39633
39634
39635
39636
39637
39638
39639
39640
39641
39642
39643
39644
39645
39646
39647
39648
39649
39650
39651
39652
39653
39654
39655
39656
39657
39658
39659
39660
39661
39662
39663
39664
39665
39666
39667
39668
39669
39670
39671
39672
39673
39674
39675
39676
39677
39678
39679
39680
39681
39682
39683
39684
39685
39686
39687
39688
39689
39690
39691
39692
39693
39694
39695
39696
39697
39698
39699
39700
39701
39702
39703
39704
39705
39706
39707
39708
39709
39710
39711
39712
39713
39714
39715
39716
39717
39718
39719
39720
39721
39722
39723
39724
39725
39726
39727
39728
39729
39730
39731
39732
39733
39734
39735
39736
39737
39738
39739
39740
39741
39742
39743
39744
39745
39746
39747
39748
39749
39750
39751
39752
39753
39754
39755
39756
39757
39758
39759
39760
39761
39762
39763
39764
39765
39766
39767
39768
39769
39770
39771
39772
39773
39774
39775
39776
39777
39778
39779
39780
39781
39782
39783
39784
39785
39786
39787
39788
39789
39790
39791
39792
39793
39794
39795
39796
39797
39798
39799
39800
39801
39802
39803
39804
39805
39806
39807
39808
39809
39810
39811
39812
39813
39814
39815
39816
39817
39818
39819
39820
39821
39822
39823
39824
39825
39826
39827
39828
39829
39830
39831
39832
39833
39834
39835
39836
39837
39838
39839
39840
39841
39842
39843
39844
39845
39846
39847
39848
39849
39850
39851
39852
39853
39854
39855
39856
39857
39858
39859
39860
39861
39862
39863
39864
39865
39866
39867
39868
39869
39870
39871
39872
39873
39874
39875
39876
39877
39878
39879
39880
39881
39882
39883
39884
39885
39886
39887
39888
39889
39890
39891
39892
39893
39894
39895
39896
39897
39898
39899
39900
39901
39902
39903
39904
39905
39906
39907
39908
39909
39910
39911
39912
39913
39914
39915
39916
39917
39918
39919
39920
39921
39922
39923
39924
39925
39926
39927
39928
39929
39930
39931
39932
39933
39934
39935
39936
39937
39938
39939
39940
39941
39942
39943
39944
39945
39946
39947
39948
39949
39950
39951
39952
39953
39954
39955
39956
39957
39958
39959
39960
39961
39962
39963
39964
39965
39966
39967
39968
39969
39970
39971
39972
39973
39974
39975
39976
39977
39978
39979
39980
39981
39982
39983
39984
39985
39986
39987
39988
39989
39990
39991
39992
39993
39994
39995
39996
39997
39998
39999
40000
40001
40002
40003
40004
40005
40006
40007
40008
40009
40010
40011
40012
40013
40014
40015
40016
40017
40018
40019
40020
40021
40022
40023
40024
40025
40026
40027
40028
40029
40030
40031
40032
40033
40034
40035
40036
40037
40038
40039
40040
40041
40042
40043
40044
40045
40046
40047
40048
40049
40050
40051
40052
40053
40054
40055
40056
40057
40058
40059
40060
40061
40062
40063
40064
40065
40066
40067
40068
40069
40070
40071
40072
40073
40074
40075
40076
40077
40078
40079
40080
40081
40082
40083
40084
40085
40086
40087
40088
40089
40090
40091
40092
40093
40094
40095
40096
40097
40098
40099
40100
40101
40102
40103
40104
40105
40106
40107
40108
40109
40110
40111
40112
40113
40114
40115
40116
40117
40118
40119
40120
40121
40122
40123
40124
40125
40126
40127
40128
40129
40130
40131
40132
40133
40134
40135
40136
40137
40138
40139
40140
40141
40142
40143
40144
40145
40146
40147
40148
40149
40150
40151
40152
40153
40154
40155
40156
40157
40158
40159
40160
40161
40162
40163
40164
40165
40166
40167
40168
40169
40170
40171
40172
40173
40174
40175
40176
40177
40178
40179
40180
40181
40182
40183
40184
40185
40186
40187
40188
40189
40190
40191
40192
40193
40194
40195
40196
40197
40198
40199
40200
40201
40202
40203
40204
40205
40206
40207
40208
40209
40210
40211
40212
40213
40214
40215
40216
40217
40218
40219
40220
40221
40222
40223
40224
40225
40226
40227
40228
40229
40230
40231
40232
40233
40234
40235
40236
40237
40238
40239
40240
40241
40242
40243
40244
40245
40246
40247
40248
40249
40250
40251
40252
40253
40254
40255
40256
40257
40258
40259
40260
40261
40262
40263
40264
40265
40266
40267
40268
40269
40270
40271
40272
40273
40274
40275
40276
40277
40278
40279
40280
40281
40282
40283
40284
40285
40286
40287
40288
40289
40290
40291
40292
40293
40294
40295
40296
40297
40298
40299
40300
40301
40302
40303
40304
40305
40306
40307
40308
40309
40310
40311
40312
40313
40314
40315
40316
40317
40318
40319
40320
40321
40322
40323
40324
40325
40326
40327
40328
40329
40330
40331
40332
40333
40334
40335
40336
40337
40338
40339
40340
40341
40342
40343
40344
40345
40346
40347
40348
40349
40350
40351
40352
40353
40354
40355
40356
40357
40358
40359
40360
40361
40362
40363
40364
40365
40366
40367
40368
40369
40370
40371
40372
40373
40374
40375
40376
40377
40378
40379
40380
40381
40382
40383
40384
40385
40386
40387
40388
40389
40390
40391
40392
40393
40394
40395
40396
40397
40398
40399
40400
40401
40402
40403
40404
40405
40406
40407
40408
40409
40410
40411
40412
40413
40414
40415
40416
40417
40418
40419
40420
40421
40422
40423
40424
40425
40426
40427
40428
40429
40430
40431
40432
40433
40434
40435
40436
40437
40438
40439
40440
40441
40442
40443
40444
40445
40446
40447
40448
40449
40450
40451
40452
40453
40454
40455
40456
40457
40458
40459
40460
40461
40462
40463
40464
40465
40466
40467
40468
40469
40470
40471
40472
40473
40474
40475
40476
40477
40478
40479
40480
40481
40482
40483
40484
40485
40486
40487
40488
40489
40490
40491
40492
40493
40494
40495
40496
40497
40498
40499
40500
40501
40502
40503
40504
40505
40506
40507
40508
40509
40510
40511
40512
40513
40514
40515
40516
40517
40518
40519
40520
40521
40522
40523
40524
40525
40526
40527
40528
40529
40530
40531
40532
40533
40534
40535
40536
40537
40538
40539
40540
40541
40542
40543
40544
40545
40546
40547
40548
40549
40550
40551
40552
40553
40554
40555
40556
40557
40558
40559
40560
40561
40562
40563
40564
40565
40566
40567
40568
40569
40570
40571
40572
40573
40574
40575
40576
40577
40578
40579
40580
40581
40582
40583
40584
40585
40586
40587
40588
40589
40590
40591
40592
40593
40594
40595
40596
40597
40598
40599
40600
40601
40602
40603
40604
40605
40606
40607
40608
40609
40610
40611
40612
40613
40614
40615
40616
40617
40618
40619
40620
40621
40622
40623
40624
40625
40626
40627
40628
40629
40630
40631
40632
40633
40634
40635
40636
40637
40638
40639
40640
40641
40642
40643
40644
40645
40646
40647
40648
40649
40650
40651
40652
40653
40654
40655
40656
40657
40658
40659
40660
40661
40662
40663
40664
40665
40666
40667
40668
40669
40670
40671
40672
40673
40674
40675
40676
40677
40678
40679
40680
40681
40682
40683
40684
40685
40686
40687
40688
40689
40690
40691
40692
40693
40694
40695
40696
40697
40698
40699
40700
40701
40702
40703
40704
40705
40706
40707
40708
40709
40710
40711
40712
40713
40714
40715
40716
40717
40718
40719
40720
40721
40722
40723
40724
40725
40726
40727
40728
40729
40730
40731
40732
40733
40734
40735
40736
40737
40738
40739
40740
40741
40742
40743
40744
40745
40746
40747
40748
40749
40750
40751
40752
40753
40754
40755
40756
40757
40758
40759
40760
40761
40762
40763
40764
40765
40766
40767
40768
40769
40770
40771
40772
40773
40774
40775
40776
40777
40778
40779
40780
40781
40782
40783
40784
40785
40786
40787
40788
40789
40790
40791
40792
40793
40794
40795
40796
40797
40798
40799
40800
40801
40802
40803
40804
40805
40806
40807
40808
40809
40810
40811
40812
40813
40814
40815
40816
40817
40818
40819
40820
40821
40822
40823
40824
40825
40826
40827
40828
40829
40830
40831
40832
40833
40834
40835
40836
40837
40838
40839
40840
40841
40842
40843
40844
40845
40846
40847
40848
40849
40850
40851
40852
40853
40854
40855
40856
40857
40858
40859
40860
40861
40862
40863
40864
40865
40866
40867
40868
40869
40870
40871
40872
40873
40874
40875
40876
40877
40878
40879
40880
40881
40882
40883
40884
40885
40886
40887
40888
40889
40890
40891
40892
40893
40894
40895
40896
40897
40898
40899
40900
40901
40902
40903
40904
40905
40906
40907
40908
40909
40910
40911
40912
40913
40914
40915
40916
40917
40918
40919
40920
40921
40922
40923
40924
40925
40926
40927
40928
40929
40930
40931
40932
40933
40934
40935
40936
40937
40938
40939
40940
40941
40942
40943
40944
40945
40946
40947
40948
40949
40950
40951
40952
40953
40954
40955
40956
40957
40958
40959
40960
40961
40962
40963
40964
40965
40966
40967
40968
40969
40970
40971
40972
40973
40974
40975
40976
40977
40978
40979
40980
40981
40982
40983
40984
40985
40986
40987
40988
40989
40990
40991
40992
40993
40994
40995
40996
40997
40998
40999
41000
41001
41002
41003
41004
41005
41006
41007
41008
41009
41010
41011
41012
41013
41014
41015
41016
41017
41018
41019
41020
41021
41022
41023
41024
41025
41026
41027
41028
41029
41030
41031
41032
41033
41034
41035
41036
41037
41038
41039
41040
41041
41042
41043
41044
41045
41046
41047
41048
41049
41050
41051
41052
41053
41054
41055
41056
41057
41058
41059
41060
41061
41062
41063
41064
41065
41066
41067
41068
41069
41070
41071
41072
41073
41074
41075
41076
41077
41078
41079
41080
41081
41082
41083
41084
41085
41086
41087
41088
41089
41090
41091
41092
41093
41094
41095
41096
41097
41098
41099
41100
41101
41102
41103
41104
41105
41106
41107
41108
41109
41110
41111
41112
41113
41114
41115
41116
41117
41118
41119
41120
41121
41122
41123
41124
41125
41126
41127
41128
41129
41130
41131
41132
41133
41134
41135
41136
41137
41138
41139
41140
41141
41142
41143
41144
41145
41146
41147
41148
41149
41150
41151
41152
41153
41154
41155
41156
41157
41158
41159
41160
41161
41162
41163
41164
41165
41166
41167
41168
41169
41170
41171
41172
41173
41174
41175
41176
41177
41178
41179
41180
41181
41182
41183
41184
41185
41186
41187
41188
41189
41190
41191
41192
41193
41194
41195
41196
41197
41198
41199
41200
41201
41202
41203
41204
41205
41206
41207
41208
41209
41210
41211
41212
41213
41214
41215
41216
41217
41218
41219
41220
41221
41222
41223
41224
41225
41226
41227
41228
41229
41230
41231
41232
41233
41234
41235
41236
41237
41238
41239
41240
41241
41242
41243
41244
41245
41246
41247
41248
41249
41250
41251
41252
41253
41254
41255
41256
41257
41258
41259
41260
41261
41262
41263
41264
41265
41266
41267
41268
41269
41270
41271
41272
41273
41274
41275
41276
41277
41278
41279
41280
41281
41282
41283
41284
41285
41286
41287
41288
41289
41290
41291
41292
41293
41294
41295
41296
41297
41298
41299
41300
41301
41302
41303
41304
41305
41306
41307
41308
41309
41310
41311
41312
41313
41314
41315
41316
41317
41318
41319
41320
41321
41322
41323
41324
41325
41326
41327
41328
41329
41330
41331
41332
41333
41334
41335
41336
41337
41338
41339
41340
41341
41342
41343
41344
41345
41346
41347
41348
41349
41350
41351
41352
41353
41354
41355
41356
41357
41358
41359
41360
41361
41362
41363
41364
41365
41366
41367
41368
41369
41370
41371
41372
41373
41374
41375
41376
41377
41378
41379
41380
41381
41382
41383
41384
41385
41386
41387
41388
41389
41390
41391
41392
41393
41394
41395
41396
41397
41398
41399
41400
41401
41402
41403
41404
41405
41406
41407
41408
41409
41410
41411
41412
41413
41414
41415
41416
41417
41418
41419
41420
41421
41422
41423
41424
41425
41426
41427
41428
41429
41430
41431
41432
41433
41434
41435
41436
41437
41438
41439
41440
41441
41442
41443
41444
41445
41446
41447
41448
41449
41450
41451
41452
41453
41454
41455
41456
41457
41458
41459
41460
41461
41462
41463
41464
41465
41466
41467
41468
41469
41470
41471
41472
41473
41474
41475
41476
41477
41478
41479
41480
41481
41482
41483
41484
41485
41486
41487
41488
41489
41490
41491
41492
41493
41494
41495
41496
41497
41498
41499
41500
41501
41502
41503
41504
41505
41506
41507
41508
41509
41510
41511
41512
41513
41514
41515
41516
41517
41518
41519
41520
41521
41522
41523
41524
41525
41526
41527
41528
41529
41530
41531
41532
41533
41534
41535
41536
41537
41538
41539
41540
41541
41542
41543
41544
41545
41546
41547
41548
41549
41550
41551
41552
41553
41554
41555
41556
41557
41558
41559
41560
41561
41562
41563
41564
41565
41566
41567
41568
41569
41570
41571
41572
41573
41574
41575
41576
41577
41578
41579
41580
41581
41582
41583
41584
41585
41586
41587
41588
41589
41590
41591
41592
41593
41594
41595
41596
41597
41598
41599
41600
41601
41602
41603
41604
41605
41606
41607
41608
41609
41610
41611
41612
41613
41614
41615
41616
41617
41618
41619
41620
41621
41622
41623
41624
41625
41626
41627
41628
41629
41630
41631
41632
41633
41634
41635
41636
41637
41638
41639
41640
41641
41642
41643
41644
41645
41646
41647
41648
41649
41650
41651
41652
41653
41654
41655
41656
41657
41658
41659
41660
41661
41662
41663
41664
41665
41666
41667
41668
41669
41670
41671
41672
41673
41674
41675
41676
41677
41678
41679
41680
41681
41682
41683
41684
41685
41686
41687
41688
41689
41690
41691
41692
41693
41694
41695
41696
41697
41698
41699
41700
41701
41702
41703
41704
41705
41706
41707
41708
41709
41710
41711
41712
41713
41714
41715
41716
41717
41718
41719
41720
41721
41722
41723
41724
41725
41726
41727
41728
41729
41730
41731
41732
41733
41734
41735
41736
41737
41738
41739
41740
41741
41742
41743
41744
41745
41746
41747
41748
41749
41750
41751
41752
41753
41754
41755
41756
41757
41758
41759
41760
41761
41762
41763
41764
41765
41766
41767
41768
41769
41770
41771
41772
41773
41774
41775
41776
41777
41778
41779
41780
41781
41782
41783
41784
41785
41786
41787
41788
41789
41790
41791
41792
41793
41794
41795
41796
41797
41798
41799
41800
41801
41802
41803
41804
41805
41806
41807
41808
41809
41810
41811
41812
41813
41814
41815
41816
41817
41818
41819
41820
41821
41822
41823
41824
41825
41826
41827
41828
41829
41830
41831
41832
41833
41834
41835
41836
41837
41838
41839
41840
41841
41842
41843
41844
41845
41846
41847
41848
41849
41850
41851
41852
41853
41854
41855
41856
41857
41858
41859
41860
41861
41862
41863
41864
41865
41866
41867
41868
41869
41870
41871
41872
41873
41874
41875
41876
41877
41878
41879
41880
41881
41882
41883
41884
41885
41886
41887
41888
41889
41890
41891
41892
41893
41894
41895
41896
41897
41898
41899
41900
41901
41902
41903
41904
41905
41906
41907
41908
41909
41910
41911
41912
41913
41914
41915
41916
41917
41918
41919
41920
41921
41922
41923
41924
41925
41926
41927
41928
41929
41930
41931
41932
41933
41934
41935
41936
41937
41938
41939
41940
41941
41942
41943
41944
41945
41946
41947
41948
41949
41950
41951
41952
41953
41954
41955
41956
41957
41958
41959
41960
41961
41962
41963
41964
41965
41966
41967
41968
41969
41970
41971
41972
41973
41974
41975
41976
41977
41978
41979
41980
41981
41982
41983
41984
41985
41986
41987
41988
41989
41990
41991
41992
41993
41994
41995
41996
41997
41998
41999
42000
42001
42002
42003
42004
42005
42006
42007
42008
42009
42010
42011
42012
42013
42014
42015
42016
42017
42018
42019
42020
42021
42022
42023
42024
42025
42026
42027
42028
42029
42030
42031
42032
42033
42034
42035
42036
42037
42038
42039
42040
42041
42042
42043
42044
42045
42046
42047
42048
42049
42050
42051
42052
42053
42054
42055
42056
42057
42058
42059
42060
42061
42062
42063
42064
42065
42066
42067
42068
42069
42070
42071
42072
42073
42074
42075
42076
42077
42078
42079
42080
42081
42082
42083
42084
42085
42086
42087
42088
42089
42090
42091
42092
42093
42094
42095
42096
42097
42098
42099
42100
42101
42102
42103
42104
42105
42106
42107
42108
42109
42110
42111
42112
42113
42114
42115
42116
42117
42118
42119
42120
42121
42122
42123
42124
42125
42126
42127
42128
42129
42130
42131
42132
42133
42134
42135
42136
42137
42138
42139
42140
42141
42142
42143
42144
42145
42146
42147
42148
42149
42150
42151
42152
42153
42154
42155
42156
42157
42158
42159
42160
42161
42162
42163
42164
42165
42166
42167
42168
42169
42170
42171
42172
42173
42174
42175
42176
42177
42178
42179
42180
42181
42182
42183
42184
42185
42186
42187
42188
42189
42190
42191
42192
42193
42194
42195
42196
42197
42198
42199
42200
42201
42202
42203
42204
42205
42206
42207
42208
42209
42210
42211
42212
42213
42214
42215
42216
42217
42218
42219
42220
42221
42222
42223
42224
42225
42226
42227
42228
42229
42230
42231
42232
42233
42234
42235
42236
42237
42238
42239
42240
42241
42242
42243
42244
42245
42246
42247
42248
42249
42250
42251
42252
42253
42254
42255
42256
42257
42258
42259
42260
42261
42262
42263
42264
42265
42266
42267
42268
42269
42270
42271
42272
42273
42274
42275
42276
42277
42278
42279
42280
42281
42282
42283
42284
42285
42286
42287
42288
42289
42290
42291
42292
42293
42294
42295
42296
42297
42298
42299
42300
42301
42302
42303
42304
42305
42306
42307
42308
42309
42310
42311
42312
42313
42314
42315
42316
42317
42318
42319
42320
42321
42322
42323
42324
42325
42326
42327
42328
42329
42330
42331
42332
42333
42334
42335
42336
42337
42338
42339
42340
42341
42342
42343
42344
42345
42346
42347
42348
42349
42350
42351
42352
42353
42354
42355
42356
42357
42358
42359
42360
42361
42362
42363
42364
42365
42366
42367
42368
42369
42370
42371
42372
42373
42374
42375
42376
42377
42378
42379
42380
42381
42382
42383
42384
42385
42386
42387
42388
42389
42390
42391
42392
42393
42394
42395
42396
42397
42398
42399
42400
42401
42402
42403
42404
42405
42406
42407
42408
42409
42410
42411
42412
42413
42414
42415
42416
42417
42418
42419
42420
42421
42422
42423
42424
42425
42426
42427
42428
42429
42430
42431
42432
42433
42434
42435
42436
42437
42438
42439
42440
42441
42442
42443
42444
42445
42446
42447
42448
42449
42450
42451
42452
42453
42454
42455
42456
42457
42458
42459
42460
42461
42462
42463
42464
42465
42466
42467
42468
42469
42470
42471
42472
42473
42474
42475
42476
42477
42478
42479
42480
42481
42482
42483
42484
42485
42486
42487
42488
42489
42490
42491
42492
42493
42494
42495
42496
42497
42498
42499
42500
42501
42502
42503
42504
42505
42506
42507
42508
42509
42510
42511
42512
42513
42514
42515
42516
42517
42518
42519
42520
42521
42522
42523
42524
42525
42526
42527
42528
42529
42530
42531
42532
42533
42534
42535
42536
42537
42538
42539
42540
42541
42542
42543
42544
42545
42546
42547
42548
42549
42550
42551
42552
42553
42554
42555
42556
42557
42558
42559
42560
42561
42562
42563
42564
42565
42566
42567
42568
42569
42570
42571
42572
42573
42574
42575
42576
42577
42578
42579
42580
42581
42582
42583
42584
42585
42586
42587
42588
42589
42590
42591
42592
42593
42594
42595
42596
42597
42598
42599
42600
42601
42602
42603
42604
42605
42606
42607
42608
42609
42610
42611
42612
42613
42614
42615
42616
42617
42618
42619
42620
42621
42622
42623
42624
42625
42626
42627
42628
42629
42630
42631
42632
42633
42634
42635
42636
42637
42638
42639
42640
42641
42642
42643
42644
42645
42646
42647
42648
42649
42650
42651
42652
42653
42654
42655
42656
42657
42658
42659
42660
42661
42662
42663
42664
42665
42666
42667
42668
42669
42670
42671
42672
42673
42674
42675
42676
42677
42678
42679
42680
42681
42682
42683
42684
42685
42686
42687
42688
42689
42690
42691
42692
42693
42694
42695
42696
42697
42698
42699
42700
42701
42702
42703
42704
42705
42706
42707
42708
42709
42710
42711
42712
42713
42714
42715
42716
42717
42718
42719
42720
42721
42722
42723
42724
42725
42726
42727
42728
42729
42730
42731
42732
42733
42734
42735
42736
42737
42738
42739
42740
42741
42742
42743
42744
42745
42746
42747
42748
42749
42750
42751
42752
42753
42754
42755
42756
42757
42758
42759
42760
42761
42762
42763
42764
42765
42766
42767
42768
42769
42770
42771
42772
42773
42774
42775
42776
42777
42778
42779
42780
42781
42782
42783
42784
42785
42786
42787
42788
42789
42790
42791
42792
42793
42794
42795
42796
42797
42798
42799
42800
42801
42802
42803
42804
42805
42806
42807
42808
42809
42810
42811
42812
42813
42814
42815
42816
42817
42818
42819
42820
42821
42822
42823
42824
42825
42826
42827
42828
42829
42830
42831
42832
42833
42834
42835
42836
42837
42838
42839
42840
42841
42842
42843
42844
42845
42846
42847
42848
42849
42850
42851
42852
42853
42854
42855
42856
42857
42858
42859
42860
42861
42862
42863
42864
42865
42866
42867
42868
42869
42870
42871
42872
42873
42874
42875
42876
42877
42878
42879
42880
42881
42882
42883
42884
42885
42886
42887
42888
42889
42890
42891
42892
42893
42894
42895
42896
42897
42898
42899
42900
42901
42902
42903
42904
42905
42906
42907
42908
42909
42910
42911
42912
42913
42914
42915
42916
42917
42918
42919
42920
42921
42922
42923
42924
42925
42926
42927
42928
42929
42930
42931
42932
42933
42934
42935
42936
42937
42938
42939
42940
42941
42942
42943
42944
42945
42946
42947
42948
42949
42950
42951
42952
42953
42954
42955
42956
42957
42958
42959
42960
42961
42962
42963
42964
42965
42966
42967
42968
42969
42970
42971
42972
42973
42974
42975
42976
42977
42978
42979
42980
42981
42982
42983
42984
42985
42986
42987
42988
42989
42990
42991
42992
42993
42994
42995
42996
42997
42998
42999
43000
43001
43002
43003
43004
43005
43006
43007
43008
43009
43010
43011
43012
43013
43014
43015
43016
43017
43018
43019
43020
43021
43022
43023
43024
43025
43026
43027
43028
43029
43030
43031
43032
43033
43034
43035
43036
43037
43038
43039
43040
43041
43042
43043
43044
43045
43046
43047
43048
43049
43050
43051
43052
43053
43054
43055
43056
43057
43058
43059
43060
43061
43062
43063
43064
43065
43066
43067
43068
43069
43070
43071
43072
43073
43074
43075
43076
43077
43078
43079
43080
43081
43082
43083
43084
43085
43086
43087
43088
43089
43090
43091
43092
43093
43094
43095
43096
43097
43098
43099
43100
43101
43102
43103
43104
43105
43106
43107
43108
43109
43110
43111
43112
43113
43114
43115
43116
43117
43118
43119
43120
43121
43122
43123
43124
43125
43126
43127
43128
43129
43130
43131
43132
43133
43134
43135
43136
43137
43138
43139
43140
43141
43142
43143
43144
43145
43146
43147
43148
43149
43150
43151
43152
43153
43154
43155
43156
43157
43158
43159
43160
43161
43162
43163
43164
43165
43166
43167
43168
43169
43170
43171
43172
43173
43174
43175
43176
43177
43178
43179
43180
43181
43182
43183
43184
43185
43186
43187
43188
43189
43190
43191
43192
43193
43194
43195
43196
43197
43198
43199
43200
43201
43202
43203
43204
43205
43206
43207
43208
43209
43210
43211
43212
43213
43214
43215
43216
43217
43218
43219
43220
43221
43222
43223
43224
43225
43226
43227
43228
43229
43230
43231
43232
43233
43234
43235
43236
43237
43238
43239
43240
43241
43242
43243
43244
43245
43246
43247
43248
43249
43250
43251
43252
43253
43254
43255
43256
43257
43258
43259
43260
43261
43262
43263
43264
43265
43266
43267
43268
43269
43270
43271
43272
43273
43274
43275
43276
43277
43278
43279
43280
43281
43282
43283
43284
43285
43286
43287
43288
43289
43290
43291
43292
43293
43294
43295
43296
43297
43298
43299
43300
43301
43302
43303
43304
43305
43306
43307
43308
43309
43310
43311
43312
43313
43314
43315
43316
43317
43318
43319
43320
43321
43322
43323
43324
43325
43326
43327
43328
43329
43330
43331
43332
43333
43334
43335
43336
43337
43338
43339
43340
43341
43342
43343
43344
43345
43346
43347
43348
43349
43350
43351
43352
43353
43354
43355
43356
43357
43358
43359
43360
43361
43362
43363
43364
43365
43366
43367
43368
43369
43370
43371
43372
43373
43374
43375
43376
43377
43378
43379
43380
43381
43382
43383
43384
43385
43386
43387
43388
43389
43390
43391
43392
43393
43394
43395
43396
43397
43398
43399
43400
43401
43402
43403
43404
43405
43406
43407
43408
43409
43410
43411
43412
43413
43414
43415
43416
43417
43418
43419
43420
43421
43422
43423
43424
43425
43426
43427
43428
43429
43430
43431
43432
43433
43434
43435
43436
43437
43438
43439
43440
43441
43442
43443
43444
43445
43446
43447
43448
43449
43450
43451
43452
43453
43454
43455
43456
43457
43458
43459
43460
43461
43462
43463
43464
43465
43466
43467
43468
43469
43470
43471
43472
43473
43474
43475
43476
43477
43478
43479
43480
43481
43482
43483
43484
43485
43486
43487
43488
43489
43490
43491
43492
43493
43494
43495
43496
43497
43498
43499
43500
43501
43502
43503
43504
43505
43506
43507
43508
43509
43510
43511
43512
43513
43514
43515
43516
43517
43518
43519
43520
43521
43522
43523
43524
43525
43526
43527
43528
43529
43530
43531
43532
43533
43534
43535
43536
43537
43538
43539
43540
43541
43542
43543
43544
43545
43546
43547
43548
43549
43550
43551
43552
43553
43554
43555
43556
43557
43558
43559
43560
43561
43562
43563
43564
43565
43566
43567
43568
43569
43570
43571
43572
43573
43574
43575
43576
43577
43578
43579
43580
43581
43582
43583
43584
43585
43586
43587
43588
43589
43590
43591
43592
43593
43594
43595
43596
43597
43598
43599
43600
43601
43602
43603
43604
43605
43606
43607
43608
43609
43610
43611
43612
43613
43614
43615
43616
43617
43618
43619
43620
43621
43622
43623
43624
43625
43626
43627
43628
43629
43630
43631
43632
43633
43634
43635
43636
43637
43638
43639
43640
43641
43642
43643
43644
43645
43646
43647
43648
43649
43650
43651
43652
43653
43654
43655
43656
43657
43658
43659
43660
43661
43662
43663
43664
43665
43666
43667
43668
43669
43670
43671
43672
43673
43674
43675
43676
43677
43678
43679
43680
43681
43682
43683
43684
43685
43686
43687
43688
43689
43690
43691
43692
43693
43694
43695
43696
43697
43698
43699
43700
43701
43702
43703
43704
43705
43706
43707
43708
43709
43710
43711
43712
43713
43714
43715
43716
43717
43718
43719
43720
43721
43722
43723
43724
43725
43726
43727
43728
43729
43730
43731
43732
43733
43734
43735
43736
43737
43738
43739
43740
43741
43742
43743
43744
43745
43746
43747
43748
43749
43750
43751
43752
43753
43754
43755
43756
43757
43758
43759
43760
43761
43762
43763
43764
43765
43766
43767
43768
43769
43770
43771
43772
43773
43774
43775
43776
43777
43778
43779
43780
43781
43782
43783
43784
43785
43786
43787
43788
43789
43790
43791
43792
43793
43794
43795
43796
43797
43798
43799
43800
43801
43802
43803
43804
43805
43806
43807
43808
43809
43810
43811
43812
43813
43814
43815
43816
43817
43818
43819
43820
43821
43822
43823
43824
43825
43826
43827
43828
43829
43830
43831
43832
43833
43834
43835
43836
43837
43838
43839
43840
43841
43842
43843
43844
43845
43846
43847
43848
43849
43850
43851
43852
43853
43854
43855
43856
43857
43858
43859
43860
43861
43862
43863
43864
43865
43866
43867
43868
43869
43870
43871
43872
43873
43874
43875
43876
43877
43878
43879
43880
43881
43882
43883
43884
43885
43886
43887
43888
43889
43890
43891
43892
43893
43894
43895
43896
43897
43898
43899
43900
43901
43902
43903
43904
43905
43906
43907
43908
43909
43910
43911
43912
43913
43914
43915
43916
43917
43918
43919
43920
43921
43922
43923
43924
43925
43926
43927
43928
43929
43930
43931
43932
43933
43934
43935
43936
43937
43938
43939
43940
43941
43942
43943
43944
43945
43946
43947
43948
43949
43950
43951
43952
43953
43954
43955
43956
43957
43958
43959
43960
43961
43962
43963
43964
43965
43966
43967
43968
43969
43970
43971
43972
43973
43974
43975
43976
43977
43978
43979
43980
43981
43982
43983
43984
43985
43986
43987
43988
43989
43990
43991
43992
43993
43994
43995
43996
43997
43998
43999
44000
44001
44002
44003
44004
44005
44006
44007
44008
44009
44010
44011
44012
44013
44014
44015
44016
44017
44018
44019
44020
44021
44022
44023
44024
44025
44026
44027
44028
44029
44030
44031
44032
44033
44034
44035
44036
44037
44038
44039
44040
44041
44042
44043
44044
44045
44046
44047
44048
44049
44050
44051
44052
44053
44054
44055
44056
44057
44058
44059
44060
44061
44062
44063
44064
44065
44066
44067
44068
44069
44070
44071
44072
44073
44074
44075
44076
44077
44078
44079
44080
44081
44082
44083
44084
44085
44086
44087
44088
44089
44090
44091
44092
44093
44094
44095
44096
44097
44098
44099
44100
44101
44102
44103
44104
44105
44106
44107
44108
44109
44110
44111
44112
44113
44114
44115
44116
44117
44118
44119
44120
44121
44122
44123
44124
44125
44126
44127
44128
44129
44130
44131
44132
44133
44134
44135
44136
44137
44138
44139
44140
44141
44142
44143
44144
44145
44146
44147
44148
44149
44150
44151
44152
44153
44154
44155
44156
44157
44158
44159
44160
44161
44162
44163
44164
44165
44166
44167
44168
44169
44170
44171
44172
44173
44174
44175
44176
44177
44178
44179
44180
44181
44182
44183
44184
44185
44186
44187
44188
44189
44190
44191
44192
44193
44194
44195
44196
44197
44198
44199
44200
44201
44202
44203
44204
44205
44206
44207
44208
44209
44210
44211
44212
44213
44214
44215
44216
44217
44218
44219
44220
44221
44222
44223
44224
44225
44226
44227
44228
44229
44230
44231
44232
44233
44234
44235
44236
44237
44238
44239
44240
44241
44242
44243
44244
44245
44246
44247
44248
44249
44250
44251
44252
44253
44254
44255
44256
44257
44258
44259
44260
44261
44262
44263
44264
44265
44266
44267
44268
44269
44270
44271
44272
44273
44274
44275
44276
44277
44278
44279
44280
44281
44282
44283
44284
44285
44286
44287
44288
44289
44290
44291
44292
44293
44294
44295
44296
44297
44298
44299
44300
44301
44302
44303
44304
44305
44306
44307
44308
44309
44310
44311
44312
44313
44314
44315
44316
44317
44318
44319
44320
44321
44322
44323
44324
44325
44326
44327
44328
44329
44330
44331
44332
44333
44334
44335
44336
44337
44338
44339
44340
44341
44342
44343
44344
44345
44346
44347
44348
44349
44350
44351
44352
44353
44354
44355
44356
44357
44358
44359
44360
44361
44362
44363
44364
44365
44366
44367
44368
44369
44370
44371
44372
44373
44374
44375
44376
44377
44378
44379
44380
44381
44382
44383
44384
44385
44386
44387
44388
44389
44390
44391
44392
44393
44394
44395
44396
44397
44398
44399
44400
44401
44402
44403
44404
44405
44406
44407
44408
44409
44410
44411
44412
44413
44414
44415
44416
44417
44418
44419
44420
44421
44422
44423
44424
44425
44426
44427
44428
44429
44430
44431
44432
44433
44434
44435
44436
44437
44438
44439
44440
44441
44442
44443
44444
44445
44446
44447
44448
44449
44450
44451
44452
44453
44454
44455
44456
44457
44458
44459
44460
44461
44462
44463
44464
44465
44466
44467
44468
44469
44470
44471
44472
44473
44474
44475
44476
44477
44478
44479
44480
44481
44482
44483
44484
44485
44486
44487
44488
44489
44490
44491
44492
44493
44494
44495
44496
44497
44498
44499
44500
44501
44502
44503
44504
44505
44506
44507
44508
44509
44510
44511
44512
44513
44514
44515
44516
44517
44518
44519
44520
44521
44522
44523
44524
44525
44526
44527
44528
44529
44530
44531
44532
44533
44534
44535
44536
44537
44538
44539
44540
44541
44542
44543
44544
44545
44546
44547
44548
44549
44550
44551
44552
44553
44554
44555
44556
44557
44558
44559
44560
44561
44562
44563
44564
44565
44566
44567
44568
44569
44570
44571
44572
44573
44574
44575
44576
44577
44578
44579
44580
44581
44582
44583
44584
44585
44586
44587
44588
44589
44590
44591
44592
44593
44594
44595
44596
44597
44598
44599
44600
44601
44602
44603
44604
44605
44606
44607
44608
44609
44610
44611
44612
44613
44614
44615
44616
44617
44618
44619
44620
44621
44622
44623
44624
44625
44626
44627
44628
44629
44630
44631
44632
44633
44634
44635
44636
44637
44638
44639
44640
44641
44642
44643
44644
44645
44646
44647
44648
44649
44650
44651
44652
44653
44654
44655
44656
44657
44658
44659
44660
44661
44662
44663
44664
44665
44666
44667
44668
44669
44670
44671
44672
44673
44674
44675
44676
44677
44678
44679
44680
44681
44682
44683
44684
44685
44686
44687
44688
44689
44690
44691
44692
44693
44694
44695
44696
44697
44698
44699
44700
44701
44702
44703
44704
44705
44706
44707
44708
44709
44710
44711
44712
44713
44714
44715
44716
44717
44718
44719
44720
44721
44722
44723
44724
44725
44726
44727
44728
44729
44730
44731
44732
44733
44734
44735
44736
44737
44738
44739
44740
44741
44742
44743
44744
44745
44746
44747
44748
44749
44750
44751
44752
44753
44754
44755
44756
44757
44758
44759
44760
44761
44762
44763
44764
44765
44766
44767
44768
44769
44770
44771
44772
44773
44774
44775
44776
44777
44778
44779
44780
44781
44782
44783
44784
44785
44786
44787
44788
44789
44790
44791
44792
44793
44794
44795
44796
44797
44798
44799
44800
44801
44802
44803
44804
44805
44806
44807
44808
44809
44810
44811
44812
44813
44814
44815
44816
44817
44818
44819
44820
44821
44822
44823
44824
44825
44826
44827
44828
44829
44830
44831
44832
44833
44834
44835
44836
44837
44838
44839
44840
44841
44842
44843
44844
44845
44846
44847
44848
44849
44850
44851
44852
44853
44854
44855
44856
44857
44858
44859
44860
44861
44862
44863
44864
44865
44866
44867
44868
44869
44870
44871
44872
44873
44874
44875
44876
44877
44878
44879
44880
44881
44882
44883
44884
44885
44886
44887
44888
44889
44890
44891
44892
44893
44894
44895
44896
44897
44898
44899
44900
44901
44902
44903
44904
44905
44906
44907
44908
44909
44910
44911
44912
44913
44914
44915
44916
44917
44918
44919
44920
44921
44922
44923
44924
44925
44926
44927
44928
44929
44930
44931
44932
44933
44934
44935
44936
44937
44938
44939
44940
44941
44942
44943
44944
44945
44946
44947
44948
44949
44950
44951
44952
44953
44954
44955
44956
44957
44958
44959
44960
44961
44962
44963
44964
44965
44966
44967
44968
44969
44970
44971
44972
44973
44974
44975
44976
44977
44978
44979
44980
44981
44982
44983
44984
44985
44986
44987
44988
44989
44990
44991
44992
44993
44994
44995
44996
44997
44998
44999
45000
45001
45002
45003
45004
45005
45006
45007
45008
45009
45010
45011
45012
45013
45014
45015
45016
45017
45018
45019
45020
45021
45022
45023
45024
45025
45026
45027
45028
45029
45030
45031
45032
45033
45034
45035
45036
45037
45038
45039
45040
45041
45042
45043
45044
45045
45046
45047
45048
45049
45050
45051
45052
45053
45054
45055
45056
45057
45058
45059
45060
45061
45062
45063
45064
45065
45066
45067
45068
45069
45070
45071
45072
45073
45074
45075
45076
45077
45078
45079
45080
45081
45082
45083
45084
45085
45086
45087
45088
45089
45090
45091
45092
45093
45094
45095
45096
45097
45098
45099
45100
45101
45102
45103
45104
45105
45106
45107
45108
45109
45110
45111
45112
45113
45114
45115
45116
45117
45118
45119
45120
45121
45122
45123
45124
45125
45126
45127
45128
45129
45130
45131
45132
45133
45134
45135
45136
45137
45138
45139
45140
45141
45142
45143
45144
45145
45146
45147
45148
45149
45150
45151
45152
45153
45154
45155
45156
45157
45158
45159
45160
45161
45162
45163
45164
45165
45166
45167
45168
45169
45170
45171
45172
45173
45174
45175
45176
45177
45178
45179
45180
45181
45182
45183
45184
45185
45186
45187
45188
45189
45190
45191
45192
45193
45194
45195
45196
45197
45198
45199
45200
45201
45202
45203
45204
45205
45206
45207
45208
45209
45210
45211
45212
45213
45214
45215
45216
45217
45218
45219
45220
45221
45222
45223
45224
45225
45226
45227
45228
45229
45230
45231
45232
45233
45234
45235
45236
45237
45238
45239
45240
45241
45242
45243
45244
45245
45246
45247
45248
45249
45250
45251
45252
45253
45254
45255
45256
45257
45258
45259
45260
45261
45262
45263
45264
45265
45266
45267
45268
45269
45270
45271
45272
45273
45274
45275
45276
45277
45278
45279
45280
45281
45282
45283
45284
45285
45286
45287
45288
45289
45290
45291
45292
45293
45294
45295
45296
45297
45298
45299
45300
45301
45302
45303
45304
45305
45306
45307
45308
45309
45310
45311
45312
45313
45314
45315
45316
45317
45318
45319
45320
45321
45322
45323
45324
45325
45326
45327
45328
45329
45330
45331
45332
45333
45334
45335
45336
45337
45338
45339
45340
45341
45342
45343
45344
45345
45346
45347
45348
45349
45350
45351
45352
45353
45354
45355
45356
45357
45358
45359
45360
45361
45362
45363
45364
45365
45366
45367
45368
45369
45370
45371
45372
45373
45374
45375
45376
45377
45378
45379
45380
45381
45382
45383
45384
45385
45386
45387
45388
45389
45390
45391
45392
45393
45394
45395
45396
45397
45398
45399
45400
45401
45402
45403
45404
45405
45406
45407
45408
45409
45410
45411
45412
45413
45414
45415
45416
45417
45418
45419
45420
45421
45422
45423
45424
45425
45426
45427
45428
45429
45430
45431
45432
45433
45434
45435
45436
45437
45438
45439
45440
45441
45442
45443
45444
45445
45446
45447
45448
45449
45450
45451
45452
45453
45454
45455
45456
45457
45458
45459
45460
45461
45462
45463
45464
45465
45466
45467
45468
45469
45470
45471
45472
45473
45474
45475
45476
45477
45478
45479
45480
45481
45482
45483
45484
45485
45486
45487
45488
45489
45490
45491
45492
45493
45494
45495
45496
45497
45498
45499
45500
45501
45502
45503
45504
45505
45506
45507
45508
45509
45510
45511
45512
45513
45514
45515
45516
45517
45518
45519
45520
45521
45522
45523
45524
45525
45526
45527
45528
45529
45530
45531
45532
45533
45534
45535
45536
45537
45538
45539
45540
45541
45542
45543
45544
45545
45546
45547
45548
45549
45550
45551
45552
45553
45554
45555
45556
45557
45558
45559
45560
45561
45562
45563
45564
45565
45566
45567
45568
45569
45570
45571
45572
45573
45574
45575
45576
45577
45578
45579
45580
45581
45582
45583
45584
45585
45586
45587
45588
45589
45590
45591
45592
45593
45594
45595
45596
45597
45598
45599
45600
45601
45602
45603
45604
45605
45606
45607
45608
45609
45610
45611
45612
45613
45614
45615
45616
45617
45618
45619
45620
45621
45622
45623
45624
45625
45626
45627
45628
45629
45630
45631
45632
45633
45634
45635
45636
45637
45638
45639
45640
45641
45642
45643
45644
45645
45646
45647
45648
45649
45650
45651
45652
45653
45654
45655
45656
45657
45658
45659
45660
45661
45662
45663
45664
45665
45666
45667
45668
45669
45670
45671
45672
45673
45674
45675
45676
45677
45678
45679
45680
45681
45682
45683
45684
45685
45686
45687
45688
45689
45690
45691
45692
45693
45694
45695
45696
45697
45698
45699
45700
45701
45702
45703
45704
45705
45706
45707
45708
45709
45710
45711
45712
45713
45714
45715
45716
45717
45718
45719
45720
45721
45722
45723
45724
45725
45726
45727
45728
45729
45730
45731
45732
45733
45734
45735
45736
45737
45738
45739
45740
45741
45742
45743
45744
45745
45746
45747
45748
45749
45750
45751
45752
45753
45754
45755
45756
45757
45758
45759
45760
45761
45762
45763
45764
45765
45766
45767
45768
45769
45770
45771
45772
45773
45774
45775
45776
45777
45778
45779
45780
45781
45782
45783
45784
45785
45786
45787
45788
45789
45790
45791
45792
45793
45794
45795
45796
45797
45798
45799
45800
45801
45802
45803
45804
45805
45806
45807
45808
45809
45810
45811
45812
45813
45814
45815
45816
45817
45818
45819
45820
45821
45822
45823
45824
45825
45826
45827
45828
45829
45830
45831
45832
45833
45834
45835
45836
45837
45838
45839
45840
45841
45842
45843
45844
45845
45846
45847
45848
45849
45850
45851
45852
45853
45854
45855
45856
45857
45858
45859
45860
45861
45862
45863
45864
45865
45866
45867
45868
45869
45870
45871
45872
45873
45874
45875
45876
45877
45878
45879
45880
45881
45882
45883
45884
45885
45886
45887
45888
45889
45890
45891
45892
45893
45894
45895
45896
45897
45898
45899
45900
45901
45902
45903
45904
45905
45906
45907
45908
45909
45910
45911
45912
45913
45914
45915
45916
45917
45918
45919
45920
45921
45922
45923
45924
45925
45926
45927
45928
45929
45930
45931
45932
45933
45934
45935
45936
45937
45938
45939
45940
45941
45942
45943
45944
45945
45946
45947
45948
45949
45950
45951
45952
45953
45954
45955
45956
45957
45958
45959
45960
45961
45962
45963
45964
45965
45966
45967
45968
45969
45970
45971
45972
45973
45974
45975
45976
45977
45978
45979
45980
45981
45982
45983
45984
45985
45986
45987
45988
45989
45990
45991
45992
45993
45994
45995
45996
45997
45998
45999
46000
46001
46002
46003
46004
46005
46006
46007
46008
46009
46010
46011
46012
46013
46014
46015
46016
46017
46018
46019
46020
46021
46022
46023
46024
46025
46026
46027
46028
46029
46030
46031
46032
46033
46034
46035
46036
46037
46038
46039
46040
46041
46042
46043
46044
46045
46046
46047
46048
46049
46050
46051
46052
46053
46054
46055
46056
46057
46058
46059
46060
46061
46062
46063
46064
46065
46066
46067
46068
46069
46070
46071
46072
46073
46074
46075
46076
46077
46078
46079
46080
46081
46082
46083
46084
46085
46086
46087
46088
46089
46090
46091
46092
46093
46094
46095
46096
46097
46098
46099
46100
46101
46102
46103
46104
46105
46106
46107
46108
46109
46110
46111
46112
46113
46114
46115
46116
46117
46118
46119
46120
46121
46122
46123
46124
46125
46126
46127
46128
46129
46130
46131
46132
46133
46134
46135
46136
46137
46138
46139
46140
46141
46142
46143
46144
46145
46146
46147
46148
46149
46150
46151
46152
46153
46154
46155
46156
46157
46158
46159
46160
46161
46162
46163
46164
46165
46166
46167
46168
46169
46170
46171
46172
46173
46174
46175
46176
46177
46178
46179
46180
46181
46182
46183
46184
46185
46186
46187
46188
46189
46190
46191
46192
46193
46194
46195
46196
46197
46198
46199
46200
46201
46202
46203
46204
46205
46206
46207
46208
46209
46210
46211
46212
46213
46214
46215
46216
46217
46218
46219
46220
46221
46222
46223
46224
46225
46226
46227
46228
46229
46230
46231
46232
46233
46234
46235
46236
46237
46238
46239
46240
46241
46242
46243
46244
46245
46246
46247
46248
46249
46250
46251
46252
46253
46254
46255
46256
46257
46258
46259
46260
46261
46262
46263
46264
46265
46266
46267
46268
46269
46270
46271
46272
46273
46274
46275
46276
46277
46278
46279
46280
46281
46282
46283
46284
46285
46286
46287
46288
46289
46290
46291
46292
46293
46294
46295
46296
46297
46298
46299
46300
46301
46302
46303
46304
46305
46306
46307
46308
46309
46310
46311
46312
46313
46314
46315
46316
46317
46318
46319
46320
46321
46322
46323
46324
46325
46326
46327
46328
46329
46330
46331
46332
46333
46334
46335
46336
46337
46338
46339
46340
46341
46342
46343
46344
46345
46346
46347
46348
46349
46350
46351
46352
46353
46354
46355
46356
46357
46358
46359
46360
46361
46362
46363
46364
46365
46366
46367
46368
46369
46370
46371
46372
46373
46374
46375
46376
46377
46378
46379
46380
46381
46382
46383
46384
46385
46386
46387
46388
46389
46390
46391
46392
46393
46394
46395
46396
46397
46398
46399
46400
46401
46402
46403
46404
46405
46406
46407
46408
46409
46410
46411
46412
46413
46414
46415
46416
46417
46418
46419
46420
46421
46422
46423
46424
46425
46426
46427
46428
46429
46430
46431
46432
46433
46434
46435
46436
46437
46438
46439
46440
46441
46442
46443
46444
46445
46446
46447
46448
46449
46450
46451
46452
46453
46454
46455
46456
46457
46458
46459
46460
46461
46462
46463
46464
46465
46466
46467
46468
46469
46470
46471
46472
46473
46474
46475
46476
46477
46478
46479
46480
46481
46482
46483
46484
46485
46486
46487
46488
46489
46490
46491
46492
46493
46494
46495
46496
46497
46498
46499
46500
46501
46502
46503
46504
46505
46506
46507
46508
46509
46510
46511
46512
46513
46514
46515
46516
46517
46518
46519
46520
46521
46522
46523
46524
46525
46526
46527
46528
46529
46530
46531
46532
46533
46534
46535
46536
46537
46538
46539
46540
46541
46542
46543
46544
46545
46546
46547
46548
46549
46550
46551
46552
46553
46554
46555
46556
46557
46558
46559
46560
46561
46562
46563
46564
46565
46566
46567
46568
46569
46570
46571
46572
46573
46574
46575
46576
46577
46578
46579
46580
46581
46582
46583
46584
46585
46586
46587
46588
46589
46590
46591
46592
46593
46594
46595
46596
46597
46598
46599
46600
46601
46602
46603
46604
46605
46606
46607
46608
46609
46610
46611
46612
46613
46614
46615
46616
46617
46618
46619
46620
46621
46622
46623
46624
46625
46626
46627
46628
46629
46630
46631
46632
46633
46634
46635
46636
46637
46638
46639
46640
46641
46642
46643
46644
46645
46646
46647
46648
46649
46650
46651
46652
46653
46654
46655
46656
46657
46658
46659
46660
46661
46662
46663
46664
46665
46666
46667
46668
46669
46670
46671
46672
46673
46674
46675
46676
46677
46678
46679
46680
46681
46682
46683
46684
46685
46686
46687
46688
46689
46690
46691
46692
46693
46694
46695
46696
46697
46698
46699
46700
46701
46702
46703
46704
46705
46706
46707
46708
46709
46710
46711
46712
46713
46714
46715
46716
46717
46718
46719
46720
46721
46722
46723
46724
46725
46726
46727
46728
46729
46730
46731
46732
46733
46734
46735
46736
46737
46738
46739
46740
46741
46742
46743
46744
46745
46746
46747
46748
46749
46750
46751
46752
46753
46754
46755
46756
46757
46758
46759
46760
46761
46762
46763
46764
46765
46766
46767
46768
46769
46770
46771
46772
46773
46774
46775
46776
46777
46778
46779
46780
46781
46782
46783
46784
46785
46786
46787
46788
46789
46790
46791
46792
46793
46794
46795
46796
46797
46798
46799
46800
46801
46802
46803
46804
46805
46806
46807
46808
46809
46810
46811
46812
46813
46814
46815
46816
46817
46818
46819
46820
46821
46822
46823
46824
46825
46826
46827
46828
46829
46830
46831
46832
46833
46834
46835
46836
46837
46838
46839
46840
46841
46842
46843
46844
46845
46846
46847
46848
46849
46850
46851
46852
46853
46854
46855
46856
46857
46858
46859
46860
46861
46862
46863
46864
46865
46866
46867
46868
46869
46870
46871
46872
46873
46874
46875
46876
46877
46878
46879
46880
46881
46882
46883
46884
46885
46886
46887
46888
46889
46890
46891
46892
46893
46894
46895
46896
46897
46898
46899
46900
46901
46902
46903
46904
46905
46906
46907
46908
46909
46910
46911
46912
46913
46914
46915
46916
46917
46918
46919
46920
46921
46922
46923
46924
46925
46926
46927
46928
46929
46930
46931
46932
46933
46934
46935
46936
46937
46938
46939
46940
46941
46942
46943
46944
46945
46946
46947
46948
46949
46950
46951
46952
46953
46954
46955
46956
46957
46958
46959
46960
46961
46962
46963
46964
46965
46966
46967
46968
46969
46970
46971
46972
46973
46974
46975
46976
46977
46978
46979
46980
46981
46982
46983
46984
46985
46986
46987
46988
46989
46990
46991
46992
46993
46994
46995
46996
46997
46998
46999
47000
47001
47002
47003
47004
47005
47006
47007
47008
47009
47010
47011
47012
47013
47014
47015
47016
47017
47018
47019
47020
47021
47022
47023
47024
47025
47026
47027
47028
47029
47030
47031
47032
47033
47034
47035
47036
47037
47038
47039
47040
47041
47042
47043
47044
47045
47046
47047
47048
47049
47050
47051
47052
47053
47054
47055
47056
47057
47058
47059
47060
47061
47062
47063
47064
47065
47066
47067
47068
47069
47070
47071
47072
47073
47074
47075
47076
47077
47078
47079
47080
47081
47082
47083
47084
47085
47086
47087
47088
47089
47090
47091
47092
47093
47094
47095
47096
47097
47098
47099
47100
47101
47102
47103
47104
47105
47106
47107
47108
47109
47110
47111
47112
47113
47114
47115
47116
47117
47118
47119
47120
47121
47122
47123
47124
47125
47126
47127
47128
47129
47130
47131
47132
47133
47134
47135
47136
47137
47138
47139
47140
47141
47142
47143
47144
47145
47146
47147
47148
47149
47150
47151
47152
47153
47154
47155
47156
47157
47158
47159
47160
47161
47162
47163
47164
47165
47166
47167
47168
47169
47170
47171
47172
47173
47174
47175
47176
47177
47178
47179
47180
47181
47182
47183
47184
47185
47186
47187
47188
47189
47190
47191
47192
47193
47194
47195
47196
47197
47198
47199
47200
47201
47202
47203
47204
47205
47206
47207
47208
47209
47210
47211
47212
47213
47214
47215
47216
47217
47218
47219
47220
47221
47222
47223
47224
47225
47226
47227
47228
47229
47230
47231
47232
47233
47234
47235
47236
47237
47238
47239
47240
47241
47242
47243
47244
47245
47246
47247
47248
47249
47250
47251
47252
47253
47254
47255
47256
47257
47258
47259
47260
47261
47262
47263
47264
47265
47266
47267
47268
47269
47270
47271
47272
47273
47274
47275
47276
47277
47278
47279
47280
47281
47282
47283
47284
47285
47286
47287
47288
47289
47290
47291
47292
47293
47294
47295
47296
47297
47298
47299
47300
47301
47302
47303
47304
47305
47306
47307
47308
47309
47310
47311
47312
47313
47314
47315
47316
47317
47318
47319
47320
47321
47322
47323
47324
47325
47326
47327
47328
47329
47330
47331
47332
47333
47334
47335
47336
47337
47338
47339
47340
47341
47342
47343
47344
47345
47346
47347
47348
47349
47350
47351
47352
47353
47354
47355
47356
47357
47358
47359
47360
47361
47362
47363
47364
47365
47366
47367
47368
47369
47370
47371
47372
47373
47374
47375
47376
47377
47378
47379
47380
47381
47382
47383
47384
47385
47386
47387
47388
47389
47390
47391
47392
47393
47394
47395
47396
47397
47398
47399
47400
47401
47402
47403
47404
47405
47406
47407
47408
47409
47410
47411
47412
47413
47414
47415
47416
47417
47418
47419
47420
47421
47422
47423
47424
47425
47426
47427
47428
47429
47430
47431
47432
47433
47434
47435
47436
47437
47438
47439
47440
47441
47442
47443
47444
47445
47446
47447
47448
47449
47450
47451
47452
47453
47454
47455
47456
47457
47458
47459
47460
47461
47462
47463
47464
47465
47466
47467
47468
47469
47470
47471
47472
47473
47474
47475
47476
47477
47478
47479
47480
47481
47482
47483
47484
47485
47486
47487
47488
47489
47490
47491
47492
47493
47494
47495
47496
47497
47498
47499
47500
47501
47502
47503
47504
47505
47506
47507
47508
47509
47510
47511
47512
47513
47514
47515
47516
47517
47518
47519
47520
47521
47522
47523
47524
47525
47526
47527
47528
47529
47530
47531
47532
47533
47534
47535
47536
47537
47538
47539
47540
47541
47542
47543
47544
47545
47546
47547
47548
47549
47550
47551
47552
47553
47554
47555
47556
47557
47558
47559
47560
47561
47562
47563
47564
47565
47566
47567
47568
47569
47570
47571
47572
47573
47574
47575
47576
47577
47578
47579
47580
47581
47582
47583
47584
47585
47586
47587
47588
47589
47590
47591
47592
47593
47594
47595
47596
47597
47598
47599
47600
47601
47602
47603
47604
47605
47606
47607
47608
47609
47610
47611
47612
47613
47614
47615
47616
47617
47618
47619
47620
47621
47622
47623
47624
47625
47626
47627
47628
47629
47630
47631
47632
47633
47634
47635
47636
47637
47638
47639
47640
47641
47642
47643
47644
47645
47646
47647
47648
47649
47650
47651
47652
47653
47654
47655
47656
47657
47658
47659
47660
47661
47662
47663
47664
47665
47666
47667
47668
47669
47670
47671
47672
47673
47674
47675
47676
47677
47678
47679
47680
47681
47682
47683
47684
47685
47686
47687
47688
47689
47690
47691
47692
47693
47694
47695
47696
47697
47698
47699
47700
47701
47702
47703
47704
47705
47706
47707
47708
47709
47710
47711
47712
47713
47714
47715
47716
47717
47718
47719
47720
47721
47722
47723
47724
47725
47726
47727
47728
47729
47730
47731
47732
47733
47734
47735
47736
47737
47738
47739
47740
47741
47742
47743
47744
47745
47746
47747
47748
47749
47750
47751
47752
47753
47754
47755
47756
47757
47758
47759
47760
47761
47762
47763
47764
47765
47766
47767
47768
47769
47770
47771
47772
47773
47774
47775
47776
47777
47778
47779
47780
47781
47782
47783
47784
47785
47786
47787
47788
47789
47790
47791
47792
47793
47794
47795
47796
47797
47798
47799
47800
47801
47802
47803
47804
47805
47806
47807
47808
47809
47810
47811
47812
47813
47814
47815
47816
47817
47818
47819
47820
47821
47822
47823
47824
47825
47826
47827
47828
47829
47830
47831
47832
47833
47834
47835
47836
47837
47838
47839
47840
47841
47842
47843
47844
47845
47846
47847
47848
47849
47850
47851
47852
47853
47854
47855
47856
47857
47858
47859
47860
47861
47862
47863
47864
47865
47866
47867
47868
47869
47870
47871
47872
47873
47874
47875
47876
47877
47878
47879
47880
47881
47882
47883
47884
47885
47886
47887
47888
47889
47890
47891
47892
47893
47894
47895
47896
47897
47898
47899
47900
47901
47902
47903
47904
47905
47906
47907
47908
47909
47910
47911
47912
47913
47914
47915
47916
47917
47918
47919
47920
47921
47922
47923
47924
47925
47926
47927
47928
47929
47930
47931
47932
47933
47934
47935
47936
47937
47938
47939
47940
47941
47942
47943
47944
47945
47946
47947
47948
47949
47950
47951
47952
47953
47954
47955
47956
47957
47958
47959
47960
47961
47962
47963
47964
47965
47966
47967
47968
47969
47970
47971
47972
47973
47974
47975
47976
47977
47978
47979
47980
47981
47982
47983
47984
47985
47986
47987
47988
47989
47990
47991
47992
47993
47994
47995
47996
47997
47998
47999
48000
48001
48002
48003
48004
48005
48006
48007
48008
48009
48010
48011
48012
48013
48014
48015
48016
48017
48018
48019
48020
48021
48022
48023
48024
48025
48026
48027
48028
48029
48030
48031
48032
48033
48034
48035
48036
48037
48038
48039
48040
48041
48042
48043
48044
48045
48046
48047
48048
48049
48050
48051
48052
48053
48054
48055
48056
48057
48058
48059
48060
48061
48062
48063
48064
48065
48066
48067
48068
48069
48070
48071
48072
48073
48074
48075
48076
48077
48078
48079
48080
48081
48082
48083
48084
48085
48086
48087
48088
48089
48090
48091
48092
48093
48094
48095
48096
48097
48098
48099
48100
48101
48102
48103
48104
48105
48106
48107
48108
48109
48110
48111
48112
48113
48114
48115
48116
48117
48118
48119
48120
48121
48122
48123
48124
48125
48126
48127
48128
48129
48130
48131
48132
48133
48134
48135
48136
48137
48138
48139
48140
48141
48142
48143
48144
48145
48146
48147
48148
48149
48150
48151
48152
48153
48154
48155
48156
48157
48158
48159
48160
48161
48162
48163
48164
48165
48166
48167
48168
48169
48170
48171
48172
48173
48174
48175
48176
48177
48178
48179
48180
48181
48182
48183
48184
48185
48186
48187
48188
48189
48190
48191
48192
48193
48194
48195
48196
48197
48198
48199
48200
48201
48202
48203
48204
48205
48206
48207
48208
48209
48210
48211
48212
48213
48214
48215
48216
48217
48218
48219
48220
48221
48222
48223
48224
48225
48226
48227
48228
48229
48230
48231
48232
48233
48234
48235
48236
48237
48238
48239
48240
48241
48242
48243
48244
48245
48246
48247
48248
48249
48250
48251
48252
48253
48254
48255
48256
48257
48258
48259
48260
48261
48262
48263
48264
48265
48266
48267
48268
48269
48270
48271
48272
48273
48274
48275
48276
48277
48278
48279
48280
48281
48282
48283
48284
48285
48286
48287
48288
48289
48290
48291
48292
48293
48294
48295
48296
48297
48298
48299
48300
48301
48302
48303
48304
48305
48306
48307
48308
48309
48310
48311
48312
48313
48314
48315
48316
48317
48318
48319
48320
48321
48322
48323
48324
48325
48326
48327
48328
48329
48330
48331
48332
48333
48334
48335
48336
48337
48338
48339
48340
48341
48342
48343
48344
48345
48346
48347
48348
48349
48350
48351
48352
48353
48354
48355
48356
48357
48358
48359
48360
48361
48362
48363
48364
48365
48366
48367
48368
48369
48370
48371
48372
48373
48374
48375
48376
48377
48378
48379
48380
48381
48382
48383
48384
48385
48386
48387
48388
48389
48390
48391
48392
48393
48394
48395
48396
48397
48398
48399
48400
48401
48402
48403
48404
48405
48406
48407
48408
48409
48410
48411
48412
48413
48414
48415
48416
48417
48418
48419
48420
48421
48422
48423
48424
48425
48426
48427
48428
48429
48430
48431
48432
48433
48434
48435
48436
48437
48438
48439
48440
48441
48442
48443
48444
48445
48446
48447
48448
48449
48450
48451
48452
48453
48454
48455
48456
48457
48458
48459
48460
48461
48462
48463
48464
48465
48466
48467
48468
48469
48470
48471
48472
48473
48474
48475
48476
48477
48478
48479
48480
48481
48482
48483
48484
48485
48486
48487
48488
48489
48490
48491
48492
48493
48494
48495
48496
48497
48498
48499
48500
48501
48502
48503
48504
48505
48506
48507
48508
48509
48510
48511
48512
48513
48514
48515
48516
48517
48518
48519
48520
48521
48522
48523
48524
48525
48526
48527
48528
48529
48530
48531
48532
48533
48534
48535
48536
48537
48538
48539
48540
48541
48542
48543
48544
48545
48546
48547
48548
48549
48550
48551
48552
48553
48554
48555
48556
48557
48558
48559
48560
48561
48562
48563
48564
48565
48566
48567
48568
48569
48570
48571
48572
48573
48574
48575
48576
48577
48578
48579
48580
48581
48582
48583
48584
48585
48586
48587
48588
48589
48590
48591
48592
48593
48594
48595
48596
48597
48598
48599
48600
48601
48602
48603
48604
48605
48606
48607
48608
48609
48610
48611
48612
48613
48614
48615
48616
48617
48618
48619
48620
48621
48622
48623
48624
48625
48626
48627
48628
48629
48630
48631
48632
48633
48634
48635
48636
48637
48638
48639
48640
48641
48642
48643
48644
48645
48646
48647
48648
48649
48650
48651
48652
48653
48654
48655
48656
48657
48658
48659
48660
48661
48662
48663
48664
48665
48666
48667
48668
48669
48670
48671
48672
48673
48674
48675
48676
48677
48678
48679
48680
48681
48682
48683
48684
48685
48686
48687
48688
48689
48690
48691
48692
48693
48694
48695
48696
48697
48698
48699
48700
48701
48702
48703
48704
48705
48706
48707
48708
48709
48710
48711
48712
48713
48714
48715
48716
48717
48718
48719
48720
48721
48722
48723
48724
48725
48726
48727
48728
48729
48730
48731
48732
48733
48734
48735
48736
48737
48738
48739
48740
48741
48742
48743
48744
48745
48746
48747
48748
48749
48750
48751
48752
48753
48754
48755
48756
48757
48758
48759
48760
48761
48762
48763
48764
48765
48766
48767
48768
48769
48770
48771
48772
48773
48774
48775
48776
48777
48778
48779
48780
48781
48782
48783
48784
48785
48786
48787
48788
48789
48790
48791
48792
48793
48794
48795
48796
48797
48798
48799
48800
48801
48802
48803
48804
48805
48806
48807
48808
48809
48810
48811
48812
48813
48814
48815
48816
48817
48818
48819
48820
48821
48822
48823
48824
48825
48826
48827
48828
48829
48830
48831
48832
48833
48834
48835
48836
48837
48838
48839
48840
48841
48842
48843
48844
48845
48846
48847
48848
48849
48850
48851
48852
48853
48854
48855
48856
48857
48858
48859
48860
48861
48862
48863
48864
48865
48866
48867
48868
48869
48870
48871
48872
48873
48874
48875
48876
48877
48878
48879
48880
48881
48882
48883
48884
48885
48886
48887
48888
48889
48890
48891
48892
48893
48894
48895
48896
48897
48898
48899
48900
48901
48902
48903
48904
48905
48906
48907
48908
48909
48910
48911
48912
48913
48914
48915
48916
48917
48918
48919
48920
48921
48922
48923
48924
48925
48926
48927
48928
48929
48930
48931
48932
48933
48934
48935
48936
48937
48938
48939
48940
48941
48942
48943
48944
48945
48946
48947
48948
48949
48950
48951
48952
48953
48954
48955
48956
48957
48958
48959
48960
48961
48962
48963
48964
48965
48966
48967
48968
48969
48970
48971
48972
48973
48974
48975
48976
48977
48978
48979
48980
48981
48982
48983
48984
48985
48986
48987
48988
48989
48990
48991
48992
48993
48994
48995
48996
48997
48998
48999
49000
49001
49002
49003
49004
49005
49006
49007
49008
49009
49010
49011
49012
49013
49014
49015
49016
49017
49018
49019
49020
49021
49022
49023
49024
49025
49026
49027
49028
49029
49030
49031
49032
49033
49034
49035
49036
49037
49038
49039
49040
49041
49042
49043
49044
49045
49046
49047
49048
49049
49050
49051
49052
49053
49054
49055
49056
49057
49058
49059
49060
49061
49062
49063
49064
49065
49066
49067
49068
49069
49070
49071
49072
49073
49074
49075
49076
49077
49078
49079
49080
49081
49082
49083
49084
49085
49086
49087
49088
49089
49090
49091
49092
49093
49094
49095
49096
49097
49098
49099
49100
49101
49102
49103
49104
49105
49106
49107
49108
49109
49110
49111
49112
49113
49114
49115
49116
49117
49118
49119
49120
49121
49122
49123
49124
49125
49126
49127
49128
49129
49130
49131
49132
49133
49134
49135
49136
49137
49138
49139
49140
49141
49142
49143
49144
49145
49146
49147
49148
49149
49150
49151
49152
49153
49154
49155
49156
49157
49158
49159
49160
49161
49162
49163
49164
49165
49166
49167
49168
49169
49170
49171
49172
49173
49174
49175
49176
49177
49178
49179
49180
49181
49182
49183
49184
49185
49186
49187
49188
49189
49190
49191
49192
49193
49194
49195
49196
49197
49198
49199
49200
49201
49202
49203
49204
49205
49206
49207
49208
49209
49210
49211
49212
49213
49214
49215
49216
49217
49218
49219
49220
49221
49222
49223
49224
49225
49226
49227
49228
49229
49230
49231
49232
49233
49234
49235
49236
49237
49238
49239
49240
49241
49242
49243
49244
49245
49246
49247
49248
49249
49250
49251
49252
49253
49254
49255
49256
49257
49258
49259
49260
49261
49262
49263
49264
49265
49266
49267
49268
49269
49270
49271
49272
49273
49274
49275
49276
49277
49278
49279
49280
49281
49282
49283
49284
49285
49286
49287
49288
49289
49290
49291
49292
49293
49294
49295
49296
49297
49298
49299
49300
49301
49302
49303
49304
49305
49306
49307
49308
49309
49310
49311
49312
49313
49314
49315
49316
49317
49318
49319
49320
49321
49322
49323
49324
49325
49326
49327
49328
49329
49330
49331
49332
49333
49334
49335
49336
49337
49338
49339
49340
49341
49342
49343
49344
49345
49346
49347
49348
49349
49350
49351
49352
49353
49354
49355
49356
49357
49358
49359
49360
49361
49362
49363
49364
49365
49366
49367
49368
49369
49370
49371
49372
49373
49374
49375
49376
49377
49378
49379
49380
49381
49382
49383
49384
49385
49386
49387
49388
49389
49390
49391
49392
49393
49394
49395
49396
49397
49398
49399
49400
49401
49402
49403
49404
49405
49406
49407
49408
49409
49410
49411
49412
49413
49414
49415
49416
49417
49418
49419
49420
49421
49422
49423
49424
49425
49426
49427
49428
49429
49430
49431
49432
49433
49434
49435
49436
49437
49438
49439
49440
49441
49442
49443
49444
49445
49446
49447
49448
49449
49450
49451
49452
49453
49454
49455
49456
49457
49458
49459
49460
49461
49462
49463
49464
49465
49466
49467
49468
49469
49470
49471
49472
49473
49474
49475
49476
49477
49478
49479
49480
49481
49482
49483
49484
49485
49486
49487
49488
49489
49490
49491
49492
49493
49494
49495
49496
49497
49498
49499
49500
49501
49502
49503
49504
49505
49506
49507
49508
49509
49510
49511
49512
49513
49514
49515
49516
49517
49518
49519
49520
49521
49522
49523
49524
49525
49526
49527
49528
49529
49530
49531
49532
49533
49534
49535
49536
49537
49538
49539
49540
49541
49542
49543
49544
49545
49546
49547
49548
49549
49550
49551
49552
49553
49554
49555
49556
49557
49558
49559
49560
49561
49562
49563
49564
49565
49566
49567
49568
49569
49570
49571
49572
49573
49574
49575
49576
49577
49578
49579
49580
49581
49582
49583
49584
49585
49586
49587
49588
49589
49590
49591
49592
49593
49594
49595
49596
49597
49598
49599
49600
49601
49602
49603
49604
49605
49606
49607
49608
49609
49610
49611
49612
49613
49614
49615
49616
49617
49618
49619
49620
49621
49622
49623
49624
49625
49626
49627
49628
49629
49630
49631
49632
49633
49634
49635
49636
49637
49638
49639
49640
49641
49642
49643
49644
49645
49646
49647
49648
49649
49650
49651
49652
49653
49654
49655
49656
49657
49658
49659
49660
49661
49662
49663
49664
49665
49666
49667
49668
49669
49670
49671
49672
49673
49674
49675
49676
49677
49678
49679
49680
49681
49682
49683
49684
49685
49686
49687
49688
49689
49690
49691
49692
49693
49694
49695
49696
49697
49698
49699
49700
49701
49702
49703
49704
49705
49706
49707
49708
49709
49710
49711
49712
49713
49714
49715
49716
49717
49718
49719
49720
49721
49722
49723
49724
49725
49726
49727
49728
49729
49730
49731
49732
49733
49734
49735
49736
49737
49738
49739
49740
49741
49742
49743
49744
49745
49746
49747
49748
49749
49750
49751
49752
49753
49754
49755
49756
49757
49758
49759
49760
49761
49762
49763
49764
49765
49766
49767
49768
49769
49770
49771
49772
49773
49774
49775
49776
49777
49778
49779
49780
49781
49782
49783
49784
49785
49786
49787
49788
49789
49790
49791
49792
49793
49794
49795
49796
49797
49798
49799
49800
49801
49802
49803
49804
49805
49806
49807
49808
49809
49810
49811
49812
49813
49814
49815
49816
49817
49818
49819
49820
49821
49822
49823
49824
49825
49826
49827
49828
49829
49830
49831
49832
49833
49834
49835
49836
49837
49838
49839
49840
49841
49842
49843
49844
49845
49846
49847
49848
49849
49850
49851
49852
49853
49854
49855
49856
49857
49858
49859
49860
49861
49862
49863
49864
49865
49866
49867
49868
49869
49870
49871
49872
49873
49874
49875
49876
49877
49878
49879
49880
49881
49882
49883
49884
49885
49886
49887
49888
49889
49890
49891
49892
49893
49894
49895
49896
49897
49898
49899
49900
49901
49902
49903
49904
49905
49906
49907
49908
49909
49910
49911
49912
49913
49914
49915
49916
49917
49918
49919
49920
49921
49922
49923
49924
49925
49926
49927
49928
49929
49930
49931
49932
49933
49934
49935
49936
49937
49938
49939
49940
49941
49942
49943
49944
49945
49946
49947
49948
49949
49950
49951
49952
49953
49954
49955
49956
49957
49958
49959
49960
49961
49962
49963
49964
49965
49966
49967
49968
49969
49970
49971
49972
49973
49974
49975
49976
49977
49978
49979
49980
49981
49982
49983
49984
49985
49986
49987
49988
49989
49990
49991
49992
49993
49994
49995
49996
49997
49998
49999
50000
50001
50002
50003
50004
50005
50006
50007
50008
50009
50010
50011
50012
50013
50014
50015
50016
50017
50018
50019
50020
50021
50022
50023
50024
50025
50026
50027
50028
50029
50030
50031
50032
50033
50034
50035
50036
50037
50038
50039
50040
50041
50042
50043
50044
50045
50046
50047
50048
50049
50050
50051
50052
50053
50054
50055
50056
50057
50058
50059
50060
50061
50062
50063
50064
50065
50066
50067
50068
50069
50070
50071
50072
50073
50074
50075
50076
50077
50078
50079
50080
50081
50082
50083
50084
50085
50086
50087
50088
50089
50090
50091
50092
50093
50094
50095
50096
50097
50098
50099
50100
50101
50102
50103
50104
50105
50106
50107
50108
50109
50110
50111
50112
50113
50114
50115
50116
50117
50118
50119
50120
50121
50122
50123
50124
50125
50126
50127
50128
50129
50130
50131
50132
50133
50134
50135
50136
50137
50138
50139
50140
50141
50142
50143
50144
50145
50146
50147
50148
50149
50150
50151
50152
50153
50154
50155
50156
50157
50158
50159
50160
50161
50162
50163
50164
50165
50166
50167
50168
50169
50170
50171
50172
50173
50174
50175
50176
50177
50178
50179
50180
50181
50182
50183
50184
50185
50186
50187
50188
50189
50190
50191
50192
50193
50194
50195
50196
50197
50198
50199
50200
50201
50202
50203
50204
50205
50206
50207
50208
50209
50210
50211
50212
50213
50214
50215
50216
50217
50218
50219
50220
50221
50222
50223
50224
50225
50226
50227
50228
50229
50230
50231
50232
50233
50234
50235
50236
50237
50238
50239
50240
50241
50242
50243
50244
50245
50246
50247
50248
50249
50250
50251
50252
50253
50254
50255
50256
50257
50258
50259
50260
50261
50262
50263
50264
50265
50266
50267
50268
50269
50270
50271
50272
50273
50274
50275
50276
50277
50278
50279
50280
50281
50282
50283
50284
50285
50286
50287
50288
50289
50290
50291
50292
50293
50294
50295
50296
50297
50298
50299
50300
50301
50302
50303
50304
50305
50306
50307
50308
50309
50310
50311
50312
50313
50314
50315
50316
50317
50318
50319
50320
50321
50322
50323
50324
50325
50326
50327
50328
50329
50330
50331
50332
50333
50334
50335
50336
50337
50338
50339
50340
50341
50342
50343
50344
50345
50346
50347
50348
50349
50350
50351
50352
50353
50354
50355
50356
50357
50358
50359
50360
50361
50362
50363
50364
50365
50366
50367
50368
50369
50370
50371
50372
50373
50374
50375
50376
50377
50378
50379
50380
50381
50382
50383
50384
50385
50386
50387
50388
50389
50390
50391
50392
50393
50394
50395
50396
50397
50398
50399
50400
50401
50402
50403
50404
50405
50406
50407
50408
50409
50410
50411
50412
50413
50414
50415
50416
50417
50418
50419
50420
50421
50422
50423
50424
50425
50426
50427
50428
50429
50430
50431
50432
50433
50434
50435
50436
50437
50438
50439
50440
50441
50442
50443
50444
50445
50446
50447
50448
50449
50450
50451
50452
50453
50454
50455
50456
50457
50458
50459
50460
50461
50462
50463
50464
50465
50466
50467
50468
50469
50470
50471
50472
50473
50474
50475
50476
50477
50478
50479
50480
50481
50482
50483
50484
50485
50486
50487
50488
50489
50490
50491
50492
50493
50494
50495
50496
50497
50498
50499
50500
50501
50502
50503
50504
50505
50506
50507
50508
50509
50510
50511
50512
50513
50514
50515
50516
50517
50518
50519
50520
50521
50522
50523
50524
50525
50526
50527
50528
50529
50530
50531
50532
50533
50534
50535
50536
50537
50538
50539
50540
50541
50542
50543
50544
50545
50546
50547
50548
50549
50550
50551
50552
50553
50554
50555
50556
50557
50558
50559
50560
50561
50562
50563
50564
50565
50566
50567
50568
50569
50570
50571
50572
50573
50574
50575
50576
50577
50578
50579
50580
50581
50582
50583
50584
50585
50586
50587
50588
50589
50590
50591
50592
50593
50594
50595
50596
50597
50598
50599
50600
50601
50602
50603
50604
50605
50606
50607
50608
50609
50610
50611
50612
50613
50614
50615
50616
50617
50618
50619
50620
50621
50622
50623
50624
50625
50626
50627
50628
50629
50630
50631
50632
50633
50634
50635
50636
50637
50638
50639
50640
50641
50642
50643
50644
50645
50646
50647
50648
50649
50650
50651
50652
50653
50654
50655
50656
50657
50658
50659
50660
50661
50662
50663
50664
50665
50666
50667
50668
50669
50670
50671
50672
50673
50674
50675
50676
50677
50678
50679
50680
50681
50682
50683
50684
50685
50686
50687
50688
50689
50690
50691
50692
50693
50694
50695
50696
50697
50698
50699
50700
50701
50702
50703
50704
50705
50706
50707
50708
50709
50710
50711
50712
50713
50714
50715
50716
50717
50718
50719
50720
50721
50722
50723
50724
50725
50726
50727
50728
50729
50730
50731
50732
50733
50734
50735
50736
50737
50738
50739
50740
50741
50742
50743
50744
50745
50746
50747
50748
50749
50750
50751
50752
50753
50754
50755
50756
50757
50758
50759
50760
50761
50762
50763
50764
50765
50766
50767
50768
50769
50770
50771
50772
50773
50774
50775
50776
50777
50778
50779
50780
50781
50782
50783
50784
50785
50786
50787
50788
50789
50790
50791
50792
50793
50794
50795
50796
50797
50798
50799
50800
50801
50802
50803
50804
50805
50806
50807
50808
50809
50810
50811
50812
50813
50814
50815
50816
50817
50818
50819
50820
50821
50822
50823
50824
50825
50826
50827
50828
50829
50830
50831
50832
50833
50834
50835
50836
50837
50838
50839
50840
50841
50842
50843
50844
50845
50846
50847
50848
50849
50850
50851
50852
50853
50854
50855
50856
50857
50858
50859
50860
50861
50862
50863
50864
50865
50866
50867
50868
50869
50870
50871
50872
50873
50874
50875
50876
50877
50878
50879
50880
50881
50882
50883
50884
50885
50886
50887
50888
50889
50890
50891
50892
50893
50894
50895
50896
50897
50898
50899
50900
50901
50902
50903
50904
50905
50906
50907
50908
50909
50910
50911
50912
50913
50914
50915
50916
50917
50918
50919
50920
50921
50922
50923
50924
50925
50926
50927
50928
50929
50930
50931
50932
50933
50934
50935
50936
50937
50938
50939
50940
50941
50942
50943
50944
50945
50946
50947
50948
50949
50950
50951
50952
50953
50954
50955
50956
50957
50958
50959
50960
50961
50962
50963
50964
50965
50966
50967
50968
50969
50970
50971
50972
50973
50974
50975
50976
50977
50978
50979
50980
50981
50982
50983
50984
50985
50986
50987
50988
50989
50990
50991
50992
50993
50994
50995
50996
50997
50998
50999
51000
51001
51002
51003
51004
51005
51006
51007
51008
51009
51010
51011
51012
51013
51014
51015
51016
51017
51018
51019
51020
51021
51022
51023
51024
51025
51026
51027
51028
51029
51030
51031
51032
51033
51034
51035
51036
51037
51038
51039
51040
51041
51042
51043
51044
51045
51046
51047
51048
51049
51050
51051
51052
51053
51054
51055
51056
51057
51058
51059
51060
51061
51062
51063
51064
51065
51066
51067
51068
51069
51070
51071
51072
51073
51074
51075
51076
51077
51078
51079
51080
51081
51082
51083
51084
51085
51086
51087
51088
51089
51090
51091
51092
51093
51094
51095
51096
51097
51098
51099
51100
51101
51102
51103
51104
51105
51106
51107
51108
51109
51110
51111
51112
51113
51114
51115
51116
51117
51118
51119
51120
51121
51122
51123
51124
51125
51126
51127
51128
51129
51130
51131
51132
51133
51134
51135
51136
51137
51138
51139
51140
51141
51142
51143
51144
51145
51146
51147
51148
51149
51150
51151
51152
51153
51154
51155
51156
51157
51158
51159
51160
51161
51162
51163
51164
51165
51166
51167
51168
51169
51170
51171
51172
51173
51174
51175
51176
51177
51178
51179
51180
51181
51182
51183
51184
51185
51186
51187
51188
51189
51190
51191
51192
51193
51194
51195
51196
51197
51198
51199
51200
51201
51202
51203
51204
51205
51206
51207
51208
51209
51210
51211
51212
51213
51214
51215
51216
51217
51218
51219
51220
51221
51222
51223
51224
51225
51226
51227
51228
51229
51230
51231
51232
51233
51234
51235
51236
51237
51238
51239
51240
51241
51242
51243
51244
51245
51246
51247
51248
51249
51250
51251
51252
51253
51254
51255
51256
51257
51258
51259
51260
51261
51262
51263
51264
51265
51266
51267
51268
51269
51270
51271
51272
51273
51274
51275
51276
51277
51278
51279
51280
51281
51282
51283
51284
51285
51286
51287
51288
51289
51290
51291
51292
51293
51294
51295
51296
51297
51298
51299
51300
51301
51302
51303
51304
51305
51306
51307
51308
51309
51310
51311
51312
51313
51314
51315
51316
51317
51318
51319
51320
51321
51322
51323
51324
51325
51326
51327
51328
51329
51330
51331
51332
51333
51334
51335
51336
51337
51338
51339
51340
51341
51342
51343
51344
51345
51346
51347
51348
51349
51350
51351
51352
51353
51354
51355
51356
51357
51358
51359
51360
51361
51362
51363
51364
51365
51366
51367
51368
51369
51370
51371
51372
51373
51374
51375
51376
51377
51378
51379
51380
51381
51382
51383
51384
51385
51386
51387
51388
51389
51390
51391
51392
51393
51394
51395
51396
51397
51398
51399
51400
51401
51402
51403
51404
51405
51406
51407
51408
51409
51410
51411
51412
51413
51414
51415
51416
51417
51418
51419
51420
51421
51422
51423
51424
51425
51426
51427
51428
51429
51430
51431
51432
51433
51434
51435
51436
51437
51438
51439
51440
51441
51442
51443
51444
51445
51446
51447
51448
51449
51450
51451
51452
51453
51454
51455
51456
51457
51458
51459
51460
51461
51462
51463
51464
51465
51466
51467
51468
51469
51470
51471
51472
51473
51474
51475
51476
51477
51478
51479
51480
51481
51482
51483
51484
51485
51486
51487
51488
51489
51490
51491
51492
51493
51494
51495
51496
51497
51498
51499
51500
51501
51502
51503
51504
51505
51506
51507
51508
51509
51510
51511
51512
51513
51514
51515
51516
51517
51518
51519
51520
51521
51522
51523
51524
51525
51526
51527
51528
51529
51530
51531
51532
51533
51534
51535
51536
51537
51538
51539
51540
51541
51542
51543
51544
51545
51546
51547
51548
51549
51550
51551
51552
51553
51554
51555
51556
51557
51558
51559
51560
51561
51562
51563
51564
51565
51566
51567
51568
51569
51570
51571
51572
51573
51574
51575
51576
51577
51578
51579
51580
51581
51582
51583
51584
51585
51586
51587
51588
51589
51590
51591
51592
51593
51594
51595
51596
51597
51598
51599
51600
51601
51602
51603
51604
51605
51606
51607
51608
51609
51610
51611
51612
51613
51614
51615
51616
51617
51618
51619
51620
51621
51622
51623
51624
51625
51626
51627
51628
51629
51630
51631
51632
51633
51634
51635
51636
51637
51638
51639
51640
51641
51642
51643
51644
51645
51646
51647
51648
51649
51650
51651
51652
51653
51654
51655
51656
51657
51658
51659
51660
51661
51662
51663
51664
51665
51666
51667
51668
51669
51670
51671
51672
51673
51674
51675
51676
51677
51678
51679
51680
51681
51682
51683
51684
51685
51686
51687
51688
51689
51690
51691
51692
51693
51694
51695
51696
51697
51698
51699
51700
51701
51702
51703
51704
51705
51706
51707
51708
51709
51710
51711
51712
51713
51714
51715
51716
51717
51718
51719
51720
51721
51722
51723
51724
51725
51726
51727
51728
51729
51730
51731
51732
51733
51734
51735
51736
51737
51738
51739
51740
51741
51742
51743
51744
51745
51746
51747
51748
51749
51750
51751
51752
51753
51754
51755
51756
51757
51758
51759
51760
51761
51762
51763
51764
51765
51766
51767
51768
51769
51770
51771
51772
51773
51774
51775
51776
51777
51778
51779
51780
51781
51782
51783
51784
51785
51786
51787
51788
51789
51790
51791
51792
51793
51794
51795
51796
51797
51798
51799
51800
51801
51802
51803
51804
51805
51806
51807
51808
51809
51810
51811
51812
51813
51814
51815
51816
51817
51818
51819
51820
51821
51822
51823
51824
51825
51826
51827
51828
51829
51830
51831
51832
51833
51834
51835
51836
51837
51838
51839
51840
51841
51842
51843
51844
51845
51846
51847
51848
51849
51850
51851
51852
51853
51854
51855
51856
51857
51858
51859
51860
51861
51862
51863
51864
51865
51866
51867
51868
51869
51870
51871
51872
51873
51874
51875
51876
51877
51878
51879
51880
51881
51882
51883
51884
51885
51886
51887
51888
51889
51890
51891
51892
51893
51894
51895
51896
51897
51898
51899
51900
51901
51902
51903
51904
51905
51906
51907
51908
51909
51910
51911
51912
51913
51914
51915
51916
51917
51918
51919
51920
51921
51922
51923
51924
51925
51926
51927
51928
51929
51930
51931
51932
51933
51934
51935
51936
51937
51938
51939
51940
51941
51942
51943
51944
51945
51946
51947
51948
51949
51950
51951
51952
51953
51954
51955
51956
51957
51958
51959
51960
51961
51962
51963
51964
51965
51966
51967
51968
51969
51970
51971
51972
51973
51974
51975
51976
51977
51978
51979
51980
51981
51982
51983
51984
51985
51986
51987
51988
51989
51990
51991
51992
51993
51994
51995
51996
51997
51998
51999
52000
52001
52002
52003
52004
52005
52006
52007
52008
52009
52010
52011
52012
52013
52014
52015
52016
52017
52018
52019
52020
52021
52022
52023
52024
52025
52026
52027
52028
52029
52030
52031
52032
52033
52034
52035
52036
52037
52038
52039
52040
52041
52042
52043
52044
52045
52046
52047
52048
52049
52050
52051
52052
52053
52054
52055
52056
52057
52058
52059
52060
52061
52062
52063
52064
52065
52066
52067
52068
52069
52070
52071
52072
52073
52074
52075
52076
52077
52078
52079
52080
52081
52082
52083
52084
52085
52086
52087
52088
52089
52090
52091
52092
52093
52094
52095
52096
52097
52098
52099
52100
52101
52102
52103
52104
52105
52106
52107
52108
52109
52110
52111
52112
52113
52114
52115
52116
52117
52118
52119
52120
52121
52122
52123
52124
52125
52126
52127
52128
52129
52130
52131
52132
52133
52134
52135
52136
52137
52138
52139
52140
52141
52142
52143
52144
52145
52146
52147
52148
52149
52150
52151
52152
52153
52154
52155
52156
52157
52158
52159
52160
52161
52162
52163
52164
52165
52166
52167
52168
52169
52170
52171
52172
52173
52174
52175
52176
52177
52178
52179
52180
52181
52182
52183
52184
52185
52186
52187
52188
52189
52190
52191
52192
52193
52194
52195
52196
52197
52198
52199
52200
52201
52202
52203
52204
52205
52206
52207
52208
52209
52210
52211
52212
52213
52214
52215
52216
52217
52218
52219
52220
52221
52222
52223
52224
52225
52226
52227
52228
52229
52230
52231
52232
52233
52234
52235
52236
52237
52238
52239
52240
52241
52242
52243
52244
52245
52246
52247
52248
52249
52250
52251
52252
52253
52254
52255
52256
52257
52258
52259
52260
52261
52262
52263
52264
52265
52266
52267
52268
52269
52270
52271
52272
52273
52274
52275
52276
52277
52278
52279
52280
52281
52282
52283
52284
52285
52286
52287
52288
52289
52290
52291
52292
52293
52294
52295
52296
52297
52298
52299
52300
52301
52302
52303
52304
52305
52306
52307
52308
52309
52310
52311
52312
52313
52314
52315
52316
52317
52318
52319
52320
52321
52322
52323
52324
52325
52326
52327
52328
52329
52330
52331
52332
52333
52334
52335
52336
52337
52338
52339
52340
52341
52342
52343
52344
52345
52346
52347
52348
52349
52350
52351
52352
52353
52354
52355
52356
52357
52358
52359
52360
52361
52362
52363
52364
52365
52366
52367
52368
52369
52370
52371
52372
52373
52374
52375
52376
52377
52378
52379
52380
52381
52382
52383
52384
52385
52386
52387
52388
52389
52390
52391
52392
52393
52394
52395
52396
52397
52398
52399
52400
52401
52402
52403
52404
52405
52406
52407
52408
52409
52410
52411
52412
52413
52414
52415
52416
52417
52418
52419
52420
52421
52422
52423
52424
52425
52426
52427
52428
52429
52430
52431
52432
52433
52434
52435
52436
52437
52438
52439
52440
52441
52442
52443
52444
52445
52446
52447
52448
52449
52450
52451
52452
52453
52454
52455
52456
52457
52458
52459
52460
52461
52462
52463
52464
52465
52466
52467
52468
52469
52470
52471
52472
52473
52474
52475
52476
52477
52478
52479
52480
52481
52482
52483
52484
52485
52486
52487
52488
52489
52490
52491
52492
52493
52494
52495
52496
52497
52498
52499
52500
52501
52502
52503
52504
52505
52506
52507
52508
52509
52510
52511
52512
52513
52514
52515
52516
52517
52518
52519
52520
52521
52522
52523
52524
52525
52526
52527
52528
52529
52530
52531
52532
52533
52534
52535
52536
52537
52538
52539
52540
52541
52542
52543
52544
52545
52546
52547
52548
52549
52550
52551
52552
52553
52554
52555
52556
52557
52558
52559
52560
52561
52562
52563
52564
52565
52566
52567
52568
52569
52570
52571
52572
52573
52574
52575
52576
52577
52578
52579
52580
52581
52582
52583
52584
52585
52586
52587
52588
52589
52590
52591
52592
52593
52594
52595
52596
52597
52598
52599
52600
52601
52602
52603
52604
52605
52606
52607
52608
52609
52610
52611
52612
52613
52614
52615
52616
52617
52618
52619
52620
52621
52622
52623
52624
52625
52626
52627
52628
52629
52630
52631
52632
52633
52634
52635
52636
52637
52638
52639
52640
52641
52642
52643
52644
52645
52646
52647
52648
52649
52650
52651
52652
52653
52654
52655
52656
52657
52658
52659
52660
52661
52662
52663
52664
52665
52666
52667
52668
52669
52670
52671
52672
52673
52674
52675
52676
52677
52678
52679
52680
52681
52682
52683
52684
52685
52686
52687
52688
52689
52690
52691
52692
52693
52694
52695
52696
52697
52698
52699
52700
52701
52702
52703
52704
52705
52706
52707
52708
52709
52710
52711
52712
52713
52714
52715
52716
52717
52718
52719
52720
52721
52722
52723
52724
52725
52726
52727
52728
52729
52730
52731
52732
52733
52734
52735
52736
52737
52738
52739
52740
52741
52742
52743
52744
52745
52746
52747
52748
52749
52750
52751
52752
52753
52754
52755
52756
52757
52758
52759
52760
52761
52762
52763
52764
52765
52766
52767
52768
52769
52770
52771
52772
52773
52774
52775
52776
52777
52778
52779
52780
52781
52782
52783
52784
52785
52786
52787
52788
52789
52790
52791
52792
52793
52794
52795
52796
52797
52798
52799
52800
52801
52802
52803
52804
52805
52806
52807
52808
52809
52810
52811
52812
52813
52814
52815
52816
52817
52818
52819
52820
52821
52822
52823
52824
52825
52826
52827
52828
52829
52830
52831
52832
52833
52834
52835
52836
52837
52838
52839
52840
52841
52842
52843
52844
52845
52846
52847
52848
52849
52850
52851
52852
52853
52854
52855
52856
52857
52858
52859
52860
52861
52862
52863
52864
52865
52866
52867
52868
52869
52870
52871
52872
52873
52874
52875
52876
52877
52878
52879
52880
52881
52882
52883
52884
52885
52886
52887
52888
52889
52890
52891
52892
52893
52894
52895
52896
52897
52898
52899
52900
52901
52902
52903
52904
52905
52906
52907
52908
52909
52910
52911
52912
52913
52914
52915
52916
52917
52918
52919
52920
52921
52922
52923
52924
52925
52926
52927
52928
52929
52930
52931
52932
52933
52934
52935
52936
52937
52938
52939
52940
52941
52942
52943
52944
52945
52946
52947
52948
52949
52950
52951
52952
52953
52954
52955
52956
52957
52958
52959
52960
52961
52962
52963
52964
52965
52966
52967
52968
52969
52970
52971
52972
52973
52974
52975
52976
52977
52978
52979
52980
52981
52982
52983
52984
52985
52986
52987
52988
52989
52990
52991
52992
52993
52994
52995
52996
52997
52998
52999
53000
53001
53002
53003
53004
53005
53006
53007
53008
53009
53010
53011
53012
53013
53014
53015
53016
53017
53018
53019
53020
53021
53022
53023
53024
53025
53026
53027
53028
53029
53030
53031
53032
53033
53034
53035
53036
53037
53038
53039
53040
53041
53042
53043
53044
53045
53046
53047
53048
53049
53050
53051
53052
53053
53054
53055
53056
53057
53058
53059
53060
53061
53062
53063
53064
53065
53066
53067
53068
53069
53070
53071
53072
53073
53074
53075
53076
53077
53078
53079
53080
53081
53082
53083
53084
53085
53086
53087
53088
53089
53090
53091
53092
53093
53094
53095
53096
53097
53098
53099
53100
53101
53102
53103
53104
53105
53106
53107
53108
53109
53110
53111
53112
53113
53114
53115
53116
53117
53118
53119
53120
53121
53122
53123
53124
53125
53126
53127
53128
53129
53130
53131
53132
53133
53134
53135
53136
53137
53138
53139
53140
53141
53142
53143
53144
53145
53146
53147
53148
53149
53150
53151
53152
53153
53154
53155
53156
53157
53158
53159
53160
53161
53162
53163
53164
53165
53166
53167
53168
53169
53170
53171
53172
53173
53174
53175
53176
53177
53178
53179
53180
53181
53182
53183
53184
53185
53186
53187
53188
53189
53190
53191
53192
53193
53194
53195
53196
53197
53198
53199
53200
53201
53202
53203
53204
53205
53206
53207
53208
53209
53210
53211
53212
53213
53214
53215
53216
53217
53218
53219
53220
53221
53222
53223
53224
53225
53226
53227
53228
53229
53230
53231
53232
53233
53234
53235
53236
53237
53238
53239
53240
53241
53242
53243
53244
53245
53246
53247
53248
53249
53250
53251
53252
53253
53254
53255
53256
53257
53258
53259
53260
53261
53262
53263
53264
53265
53266
53267
53268
53269
53270
53271
53272
53273
53274
53275
53276
53277
53278
53279
53280
53281
53282
53283
53284
53285
53286
53287
53288
53289
53290
53291
53292
53293
53294
53295
53296
53297
53298
53299
53300
53301
53302
53303
53304
53305
53306
53307
53308
53309
53310
53311
53312
53313
53314
53315
53316
53317
53318
53319
53320
53321
53322
53323
53324
53325
53326
53327
53328
53329
53330
53331
53332
53333
53334
53335
53336
53337
53338
53339
53340
53341
53342
53343
53344
53345
53346
53347
53348
53349
53350
53351
53352
53353
53354
53355
53356
53357
53358
53359
53360
53361
53362
53363
53364
53365
53366
53367
53368
53369
53370
53371
53372
53373
53374
53375
53376
53377
53378
53379
53380
53381
53382
53383
53384
53385
53386
53387
53388
53389
53390
53391
53392
53393
53394
53395
53396
53397
53398
53399
53400
53401
53402
53403
53404
53405
53406
53407
53408
53409
53410
53411
53412
53413
53414
53415
53416
53417
53418
53419
53420
53421
53422
53423
53424
53425
53426
53427
53428
53429
53430
53431
53432
53433
53434
53435
53436
53437
53438
53439
53440
53441
53442
53443
53444
53445
53446
53447
53448
53449
53450
53451
53452
53453
53454
53455
53456
53457
53458
53459
53460
53461
53462
53463
53464
53465
53466
53467
53468
53469
53470
53471
53472
53473
53474
53475
53476
53477
53478
53479
53480
53481
53482
53483
53484
53485
53486
53487
53488
53489
53490
53491
53492
53493
53494
53495
53496
53497
53498
53499
53500
53501
53502
53503
53504
53505
53506
53507
53508
53509
53510
53511
53512
53513
53514
53515
53516
53517
53518
53519
53520
53521
53522
53523
53524
53525
53526
53527
53528
53529
53530
53531
53532
53533
53534
53535
53536
53537
53538
53539
53540
53541
53542
53543
53544
53545
53546
53547
53548
53549
53550
53551
53552
53553
53554
53555
53556
53557
53558
53559
53560
53561
53562
53563
53564
53565
53566
53567
53568
53569
53570
53571
53572
53573
53574
53575
53576
53577
53578
53579
53580
53581
53582
53583
53584
53585
53586
53587
53588
53589
53590
53591
53592
53593
53594
53595
53596
53597
53598
53599
53600
53601
53602
53603
53604
53605
53606
53607
53608
53609
53610
53611
53612
53613
53614
53615
53616
53617
53618
53619
53620
53621
53622
53623
53624
53625
53626
53627
53628
53629
53630
53631
53632
53633
53634
53635
53636
53637
53638
53639
53640
53641
53642
53643
53644
53645
53646
53647
53648
53649
53650
53651
53652
53653
53654
53655
53656
53657
53658
53659
53660
53661
53662
53663
53664
53665
53666
53667
53668
53669
53670
53671
53672
53673
53674
53675
53676
53677
53678
53679
53680
53681
53682
53683
53684
53685
53686
53687
53688
53689
53690
53691
53692
53693
53694
53695
53696
53697
53698
53699
53700
53701
53702
53703
53704
53705
53706
53707
53708
53709
53710
53711
53712
53713
53714
53715
53716
53717
53718
53719
53720
53721
53722
53723
53724
53725
53726
53727
53728
53729
53730
53731
53732
53733
53734
53735
53736
53737
53738
53739
53740
53741
53742
53743
53744
53745
53746
53747
53748
53749
53750
53751
53752
53753
53754
53755
53756
53757
53758
53759
53760
53761
53762
53763
53764
53765
53766
53767
53768
53769
53770
53771
53772
53773
53774
53775
53776
53777
53778
53779
53780
53781
53782
53783
53784
53785
53786
53787
53788
53789
53790
53791
53792
53793
53794
53795
53796
53797
53798
53799
53800
53801
53802
53803
53804
53805
53806
53807
53808
53809
53810
53811
53812
53813
53814
53815
53816
53817
53818
53819
53820
53821
53822
53823
53824
53825
53826
53827
53828
53829
53830
53831
53832
53833
53834
53835
53836
53837
53838
53839
53840
53841
53842
53843
53844
53845
53846
53847
53848
53849
53850
53851
53852
53853
53854
53855
53856
53857
53858
53859
53860
53861
53862
53863
53864
53865
53866
53867
53868
53869
53870
53871
53872
53873
53874
53875
53876
53877
53878
53879
53880
53881
53882
53883
53884
53885
53886
53887
53888
53889
53890
53891
53892
53893
53894
53895
53896
53897
53898
53899
53900
53901
53902
53903
53904
53905
53906
53907
53908
53909
53910
53911
53912
53913
53914
53915
53916
53917
53918
53919
53920
53921
53922
53923
53924
53925
53926
53927
53928
53929
53930
53931
53932
53933
53934
53935
53936
53937
53938
53939
53940
53941
53942
53943
53944
53945
53946
53947
53948
53949
53950
53951
53952
53953
53954
53955
53956
53957
53958
53959
53960
53961
53962
53963
53964
53965
53966
53967
53968
53969
53970
53971
53972
53973
53974
53975
53976
53977
53978
53979
53980
53981
53982
53983
53984
53985
53986
53987
53988
53989
53990
53991
53992
53993
53994
53995
53996
53997
53998
53999
54000
54001
54002
54003
54004
54005
54006
54007
54008
54009
54010
54011
54012
54013
54014
54015
54016
54017
54018
54019
54020
54021
54022
54023
54024
54025
54026
54027
54028
54029
54030
54031
54032
54033
54034
54035
54036
54037
54038
54039
54040
54041
54042
54043
54044
54045
54046
54047
54048
54049
54050
54051
54052
54053
54054
54055
54056
54057
54058
54059
54060
54061
54062
54063
54064
54065
54066
54067
54068
54069
54070
54071
54072
54073
54074
54075
54076
54077
54078
54079
54080
54081
54082
54083
54084
54085
54086
54087
54088
54089
54090
54091
54092
54093
54094
54095
54096
54097
54098
54099
54100
54101
54102
54103
54104
54105
54106
54107
54108
54109
54110
54111
54112
54113
54114
54115
54116
54117
54118
54119
54120
54121
54122
54123
54124
54125
54126
54127
54128
54129
54130
54131
54132
54133
54134
54135
54136
54137
54138
54139
54140
54141
54142
54143
54144
54145
54146
54147
54148
54149
54150
54151
54152
54153
54154
54155
54156
54157
54158
54159
54160
54161
54162
54163
54164
54165
54166
54167
54168
54169
54170
54171
54172
54173
54174
54175
54176
54177
54178
54179
54180
54181
54182
54183
54184
54185
54186
54187
54188
54189
54190
54191
54192
54193
54194
54195
54196
54197
54198
54199
54200
54201
54202
54203
54204
54205
54206
54207
54208
54209
54210
54211
54212
54213
54214
54215
54216
54217
54218
54219
54220
54221
54222
54223
54224
54225
54226
54227
54228
54229
54230
54231
54232
54233
54234
54235
54236
54237
54238
54239
54240
54241
54242
54243
54244
54245
54246
54247
54248
54249
54250
54251
54252
54253
54254
54255
54256
54257
54258
54259
54260
54261
54262
54263
54264
54265
54266
54267
54268
54269
54270
54271
54272
54273
54274
54275
54276
54277
54278
54279
54280
54281
54282
54283
54284
54285
54286
54287
54288
54289
54290
54291
54292
54293
54294
54295
54296
54297
54298
54299
54300
54301
54302
54303
54304
54305
54306
54307
54308
54309
54310
54311
54312
54313
54314
54315
54316
54317
54318
54319
54320
54321
54322
54323
54324
54325
54326
54327
54328
54329
54330
54331
54332
54333
54334
54335
54336
54337
54338
54339
54340
54341
54342
54343
54344
54345
54346
54347
54348
54349
54350
54351
54352
54353
54354
54355
54356
54357
54358
54359
54360
54361
54362
54363
54364
54365
54366
54367
54368
54369
54370
54371
54372
54373
54374
54375
54376
54377
54378
54379
54380
54381
54382
54383
54384
54385
54386
54387
54388
54389
54390
54391
54392
54393
54394
54395
54396
54397
54398
54399
54400
54401
54402
54403
54404
54405
54406
54407
54408
54409
54410
54411
54412
54413
54414
54415
54416
54417
54418
54419
54420
54421
54422
54423
54424
54425
54426
54427
54428
54429
54430
54431
54432
54433
54434
54435
54436
54437
54438
54439
54440
54441
54442
54443
54444
54445
54446
54447
54448
54449
54450
54451
54452
54453
54454
54455
54456
54457
54458
54459
54460
54461
54462
54463
54464
54465
54466
54467
54468
54469
54470
54471
54472
54473
54474
54475
54476
54477
54478
54479
54480
54481
54482
54483
54484
54485
54486
54487
54488
54489
54490
54491
54492
54493
54494
54495
54496
54497
54498
54499
54500
54501
54502
54503
54504
54505
54506
54507
54508
54509
54510
54511
54512
54513
54514
54515
54516
54517
54518
54519
54520
54521
54522
54523
54524
54525
54526
54527
54528
54529
54530
54531
54532
54533
54534
54535
54536
54537
54538
54539
54540
54541
54542
54543
54544
54545
54546
54547
54548
54549
54550
54551
54552
54553
54554
54555
54556
54557
54558
54559
54560
54561
54562
54563
54564
54565
54566
54567
54568
54569
54570
54571
54572
54573
54574
54575
54576
54577
54578
54579
54580
54581
54582
54583
54584
54585
54586
54587
54588
54589
54590
54591
54592
54593
54594
54595
54596
54597
54598
54599
54600
54601
54602
54603
54604
54605
54606
54607
54608
54609
54610
54611
54612
54613
54614
54615
54616
54617
54618
54619
54620
54621
54622
54623
54624
54625
54626
54627
54628
54629
54630
54631
54632
54633
54634
54635
54636
54637
54638
54639
54640
54641
54642
54643
54644
54645
54646
54647
54648
54649
54650
54651
54652
54653
54654
54655
54656
54657
54658
54659
54660
54661
54662
54663
54664
54665
54666
54667
54668
54669
54670
54671
54672
54673
54674
54675
54676
54677
54678
54679
54680
54681
54682
54683
54684
54685
54686
54687
54688
54689
54690
54691
54692
54693
54694
54695
54696
54697
54698
54699
54700
54701
54702
54703
54704
54705
54706
54707
54708
54709
54710
54711
54712
54713
54714
54715
54716
54717
54718
54719
54720
54721
54722
54723
54724
54725
54726
54727
54728
54729
54730
54731
54732
54733
54734
54735
54736
54737
54738
54739
54740
54741
54742
54743
54744
54745
54746
54747
54748
54749
54750
54751
54752
54753
54754
54755
54756
54757
54758
54759
54760
54761
54762
54763
54764
54765
54766
54767
54768
54769
54770
54771
54772
54773
54774
54775
54776
54777
54778
54779
54780
54781
54782
54783
54784
54785
54786
54787
54788
54789
54790
54791
54792
54793
54794
54795
54796
54797
54798
54799
54800
54801
54802
54803
54804
54805
54806
54807
54808
54809
54810
54811
54812
54813
54814
54815
54816
54817
54818
54819
54820
54821
54822
54823
54824
54825
54826
54827
54828
54829
54830
54831
54832
54833
54834
54835
54836
54837
54838
54839
54840
54841
54842
54843
54844
54845
54846
54847
54848
54849
54850
54851
54852
54853
54854
54855
54856
54857
54858
54859
54860
54861
54862
54863
54864
54865
54866
54867
54868
54869
54870
54871
54872
54873
54874
54875
54876
54877
54878
54879
54880
54881
54882
54883
54884
54885
54886
54887
54888
54889
54890
54891
54892
54893
54894
54895
54896
54897
54898
54899
54900
54901
54902
54903
54904
54905
54906
54907
54908
54909
54910
54911
54912
54913
54914
54915
54916
54917
54918
54919
54920
54921
54922
54923
54924
54925
54926
54927
54928
54929
54930
54931
54932
54933
54934
54935
54936
54937
54938
54939
54940
54941
54942
54943
54944
54945
54946
54947
54948
54949
54950
54951
54952
54953
54954
54955
54956
54957
54958
54959
54960
54961
54962
54963
54964
54965
54966
54967
54968
54969
54970
54971
54972
54973
54974
54975
54976
54977
54978
54979
54980
54981
54982
54983
54984
54985
54986
54987
54988
54989
54990
54991
54992
54993
54994
54995
54996
54997
54998
54999
55000
55001
55002
55003
55004
55005
55006
55007
55008
55009
55010
55011
55012
55013
55014
55015
55016
55017
55018
55019
55020
55021
55022
55023
55024
55025
55026
55027
55028
55029
55030
55031
55032
55033
55034
55035
55036
55037
55038
55039
55040
55041
55042
55043
55044
55045
55046
55047
55048
55049
55050
55051
55052
55053
55054
55055
55056
55057
55058
55059
55060
55061
55062
55063
55064
55065
55066
55067
55068
55069
55070
55071
55072
55073
55074
55075
55076
55077
55078
55079
55080
55081
55082
55083
55084
55085
55086
55087
55088
55089
55090
55091
55092
55093
55094
55095
55096
55097
55098
55099
55100
55101
55102
55103
55104
55105
55106
55107
55108
55109
55110
55111
55112
55113
55114
55115
55116
55117
55118
55119
55120
55121
55122
55123
55124
55125
55126
55127
55128
55129
55130
55131
55132
55133
55134
55135
55136
55137
55138
55139
55140
55141
55142
55143
55144
55145
55146
55147
55148
55149
55150
55151
55152
55153
55154
55155
55156
55157
55158
55159
55160
55161
55162
55163
55164
55165
55166
55167
55168
55169
55170
55171
55172
55173
55174
55175
55176
55177
55178
55179
55180
55181
55182
55183
55184
55185
55186
55187
55188
55189
55190
55191
55192
55193
55194
55195
55196
55197
55198
55199
55200
55201
55202
55203
55204
55205
55206
55207
55208
55209
55210
55211
55212
55213
55214
55215
55216
55217
55218
55219
55220
55221
55222
55223
55224
55225
55226
55227
55228
55229
55230
55231
55232
55233
55234
55235
55236
55237
55238
55239
55240
55241
55242
55243
55244
55245
55246
55247
55248
55249
55250
55251
55252
55253
55254
55255
55256
55257
55258
55259
55260
55261
55262
55263
55264
55265
55266
55267
55268
55269
55270
55271
55272
55273
55274
55275
55276
55277
55278
55279
55280
55281
55282
55283
55284
55285
55286
55287
55288
55289
55290
55291
55292
55293
55294
55295
55296
55297
55298
55299
55300
55301
55302
55303
55304
55305
55306
55307
55308
55309
55310
55311
55312
55313
55314
55315
55316
55317
55318
55319
55320
55321
55322
55323
55324
55325
55326
55327
55328
55329
55330
55331
55332
55333
55334
55335
55336
55337
55338
55339
55340
55341
55342
55343
55344
55345
55346
55347
55348
55349
55350
55351
55352
55353
55354
55355
55356
55357
55358
55359
55360
55361
55362
55363
55364
55365
55366
55367
55368
55369
55370
55371
55372
55373
55374
55375
55376
55377
55378
55379
55380
55381
55382
55383
55384
55385
55386
55387
55388
55389
55390
55391
55392
55393
55394
55395
55396
55397
55398
55399
55400
55401
55402
55403
55404
55405
55406
55407
55408
55409
55410
55411
55412
55413
55414
55415
55416
55417
55418
55419
55420
55421
55422
55423
55424
55425
55426
55427
55428
55429
55430
55431
55432
55433
55434
55435
55436
55437
55438
55439
55440
55441
55442
55443
55444
55445
55446
55447
55448
55449
55450
55451
55452
55453
55454
55455
55456
55457
55458
55459
55460
55461
55462
55463
55464
55465
55466
55467
55468
55469
55470
55471
55472
55473
55474
55475
55476
55477
55478
55479
55480
55481
55482
55483
55484
55485
55486
55487
55488
55489
55490
55491
55492
55493
55494
55495
55496
55497
55498
55499
55500
55501
55502
55503
55504
55505
55506
55507
55508
55509
55510
55511
55512
55513
55514
55515
55516
55517
55518
55519
55520
55521
55522
55523
55524
55525
55526
55527
55528
55529
55530
55531
55532
55533
55534
55535
55536
55537
55538
55539
55540
55541
55542
55543
55544
55545
55546
55547
55548
55549
55550
55551
55552
55553
55554
55555
55556
55557
55558
55559
55560
55561
55562
55563
55564
55565
55566
55567
55568
55569
55570
55571
55572
55573
55574
55575
55576
55577
55578
55579
55580
55581
55582
55583
55584
55585
55586
55587
55588
55589
55590
55591
55592
55593
55594
55595
55596
55597
55598
55599
55600
55601
55602
55603
55604
55605
55606
55607
55608
55609
55610
55611
55612
55613
55614
55615
55616
55617
55618
55619
55620
55621
55622
55623
55624
55625
55626
55627
55628
55629
55630
55631
55632
55633
55634
55635
55636
55637
55638
55639
55640
55641
55642
55643
55644
55645
55646
55647
55648
55649
55650
55651
55652
55653
55654
55655
55656
55657
55658
55659
55660
55661
55662
55663
55664
55665
55666
55667
55668
55669
55670
55671
55672
55673
55674
55675
55676
55677
55678
55679
55680
55681
55682
55683
55684
55685
55686
55687
55688
55689
55690
55691
55692
55693
55694
55695
55696
55697
55698
55699
55700
55701
55702
55703
55704
55705
55706
55707
55708
55709
55710
55711
55712
55713
55714
55715
55716
55717
55718
55719
55720
55721
55722
55723
55724
55725
55726
55727
55728
55729
55730
55731
55732
55733
55734
55735
55736
55737
55738
55739
55740
55741
55742
55743
55744
55745
55746
55747
55748
55749
55750
55751
55752
55753
55754
55755
55756
55757
55758
55759
55760
55761
55762
55763
55764
55765
55766
55767
55768
55769
55770
55771
55772
55773
55774
55775
55776
55777
55778
55779
55780
55781
55782
55783
55784
55785
55786
55787
55788
55789
55790
55791
55792
55793
55794
55795
55796
55797
55798
55799
55800
55801
55802
55803
55804
55805
55806
55807
55808
55809
55810
55811
55812
55813
55814
55815
55816
55817
55818
55819
55820
55821
55822
55823
55824
55825
55826
55827
55828
55829
55830
55831
55832
55833
55834
55835
55836
55837
55838
55839
55840
55841
55842
55843
55844
55845
55846
55847
55848
55849
55850
55851
55852
55853
55854
55855
55856
55857
55858
55859
55860
55861
55862
55863
55864
55865
55866
55867
55868
55869
55870
55871
55872
55873
55874
55875
55876
55877
55878
55879
55880
55881
55882
55883
55884
55885
55886
55887
55888
55889
55890
55891
55892
55893
55894
55895
55896
55897
55898
55899
55900
55901
55902
55903
55904
55905
55906
55907
55908
55909
55910
55911
55912
55913
55914
55915
55916
55917
55918
55919
55920
55921
55922
55923
55924
55925
55926
55927
55928
55929
55930
55931
55932
55933
55934
55935
55936
55937
55938
55939
55940
55941
55942
55943
55944
55945
55946
55947
55948
55949
55950
55951
55952
55953
55954
55955
55956
55957
55958
55959
55960
55961
55962
55963
55964
55965
55966
55967
55968
55969
55970
55971
55972
55973
55974
55975
55976
55977
55978
55979
55980
55981
55982
55983
55984
55985
55986
55987
55988
55989
55990
55991
55992
55993
55994
55995
55996
55997
55998
55999
56000
56001
56002
56003
56004
56005
56006
56007
56008
56009
56010
56011
56012
56013
56014
56015
56016
56017
56018
56019
56020
56021
56022
56023
56024
56025
56026
56027
56028
56029
56030
56031
56032
56033
56034
56035
56036
56037
56038
56039
56040
56041
56042
56043
56044
56045
56046
56047
56048
56049
56050
56051
56052
56053
56054
56055
56056
56057
56058
56059
56060
56061
56062
56063
56064
56065
56066
56067
56068
56069
56070
56071
56072
56073
56074
56075
56076
56077
56078
56079
56080
56081
56082
56083
56084
56085
56086
56087
56088
56089
56090
56091
56092
56093
56094
56095
56096
56097
56098
56099
56100
56101
56102
56103
56104
56105
56106
56107
56108
56109
56110
56111
56112
56113
56114
56115
56116
56117
56118
56119
56120
56121
56122
56123
56124
56125
56126
56127
56128
56129
56130
56131
56132
56133
56134
56135
56136
56137
56138
56139
56140
56141
56142
56143
56144
56145
56146
56147
56148
56149
56150
56151
56152
56153
56154
56155
56156
56157
56158
56159
56160
56161
56162
56163
56164
56165
\input texinfo  @c -*-texinfo-*-
@c Copyright 1997-2002 TcX AB, Detron HB und MySQL Finland AB
@c
@c *********************************************************
@c Note that @node names are used on our Website.
@c So do not change node names without checking
@c Makefile.am und SitePages first.
@c *********************************************************
@c
@c %**start of header

@c there's a better way to do this.. i just don't know it yet
@c sed will remove the "@c ifnusphere " to make this valid
@c ifnusphere @set nusphere 1

@setfilename mysql.de.info

@c We want the types in the same index
@syncodeindex tp fn

@c Get version information. This file is generated by the Makefile!!
@include include.texi

@ifclear tex-debug
@c This removes the black squares in the right margin
@finalout
@end ifclear

@c Set background für HTML
@set _body_tags BGCOLOR=silver TEXT=#000000 LINK=#101090 VLINK=#7030B0
@c Set some style elements für the manual in HTML form. 'suggested'
@c natural language colors: aqua, black, blue, fuchsia, gray, green,
@c lime, maroon, navy, olive, purple, red, silver, teal, white, und
@c yellow. From Steeve Buehler <ahr@YogElements.com>
@set _extra_head <style> code {color:purple} tt {color:green} samp {color:navy} pre {color:maroon} </style>

@settitle MySQL-Referenzhandbuch für Version @value{mysql_version}

@c We want single-sided heading format, with chapters on new pages. To
@c get double-sided format change 'on' below to 'odd'
@ifclear nusphere
@setchapternewpage on
@end ifclear

@ifset nusphere
@setchapternewpage odd
@end ifset

@paragraphindent 0

@ifset nusphere
@smallbook
@end ifset

@c %**end of header

@ifinfo
@format
START-INFO-DIR-ENTRY
* mysql: (mysql).               MySQL documentation.
END-INFO-DIR-ENTRY
@end format
@end ifinfo

@titlepage
@sp 10
@center @titlefont{MySQL-Referenzhandbuch}
@sp 10
@center Copyright @copyright{} 1997-2002 MySQL AB
@c blank page after title page makes page 1 be a page front.
@c also makes the back of the title page blank.
@page
@end titlepage

@c Short contents, blank page, long contents.
@c until i can figure out the blank page, no short contents.
@c @shortcontents
@c @page
@c @page
@contents

@c This should be added. The HTML conversion also needs a MySQL version
@c Anzahl somewhere.

@iftex
@c change this to double if you want formatting für double-sided
@c printing
@headings single

@oddheading @thischapter @| @| @thispage
@evenheading @thispage @| @| MySQL - Technische Referenz für Version @value{mysql_version}

@end iftex


@node Top, Introduction, (dir), (dir)
@c German node Top

@c @ifhtml
@c <IMG SRC="Images/mysql-logo.gif">
@c <!--Image doesn't exist. Can't find suitable replacement. (Matt) -->
@c @end ifhtml

@ifinfo
Das ist das Handbuch für das MySQL-Datenbanksystem. Diese Version gehört
zur MySQL-Version @value{mysql_version}. Sie finden ein Handbuch zu jeder
älteren Version von MySQL in der Binär- oder Quelldistribution der
entsprechenden Version.
@end ifinfo



@menu
* Introduction::                
* Deutsch::                     
* Installing::                  
* Tutorial::                    
* MySQL Database Administration::  
* MySQL Optimisation::          
* Reference::                   
* Table types::                 
* Clients::                     
* Extending MySQL::             
* Problems::                    
* Benutzer::                    
* MySQL-Benutzung durch Kunden::  
* Contrib::                     
* Credits::                     
* News::                        
* Porting::                     
* Environment variables::       
* Regexp::                      
* GPL license::                 
* LGPL license::                
* Function Index::              
* Concept Index::               
@end menu

@node Introduction, Deutsch, Top, Top
@c German node Einführung
@chapter Allgemeine Informationen über MySQL

@cindex Überblick
@cindex Allgemeine Informationen

MySQL ist ein sehr schneller und robuster, Multi-Thread und Multi-User
SQL-Datenbank-Server (SQL = Structured Query Language, strukturierte
Abfrage-Sprache).
Die Einsatzgebiete des MySQL Server liegen in Hochleistungsapplikationen
und in der Einbindung in weit verbreitete Massen-Software.
@code{MySQL} ist eine Schutzmarke von @code{MySQL AB}.

Die MySQL Software steht unter einer @code{Doppellizenz}. Sie
können sie entweder frei im Sinne der @code{GNU GENERAL PUBLIC LICENSE}
(@uref{http://www.gnu.org/licenses/}) verwenden, oder Sie erwerben eine
komerzielle Lizenz, wenn Sie nicht durch die Restriktionen der GPL
gebunden sein wollen.
@xref{Lizenzpolitik}.

@uref{http://www.mysql.com/, die MySQL Homepage}
enthält die letzten Informationen über MySQL.

Die folgende Liste beschreibt nützliche Teile des Handbuchs.

@itemize @bullet
@item
Informationen zu dem Unternehmen hinter MySQL: @ref{What is MySQL AB}.

@item
Eine Diskussion der Fähigkeiten von MySQL: @ref{Features}.

@item
Installationsanweisungen: @ref{Installing}.

@item
Tipps zur Portierung von MySQL auf neue Architekturen oder Betriebssysteme:
@ref{Porting}.

@item
Informationen zum Upgrade von einem Release der Version 3.23:
@ref{Upgrading-from-3.23}.

@item
Informationen zum Upgrade von einem Release der Version 3.22:
@ref{Upgrading-from-3.22}.

@item
Einführungs-Tutorial zu MySQL: @ref{Tutorial}.

@item
SQL-Beispiele und Informationen zu Benchmarks befinden sich im
Benchmark-Verzeichnis (@file{sql-bench} in der Distribution).

@item
Die Geschichte neuer Features und Bugfixes: @ref{News}.

@item
@c German FIX was @nqs{Feature-Probleme}; no idea what @nqs is??
Eine Liste bekannter Bugs und Feature-Probleme: @ref{Bugs}.

@item
Zukunftspläne: @ref{TODO}.

@item
Eine Liste aller Beteiligten, die zu diesem Projekt beitrugen: @ref{Credits}.
@end itemize

@strong{WICHTIG:}

Berichte zu Fehlern (oft Bugs genannt) sowie Fragen und Bemerkungen sollten
an die Mailingliste geschickt werden: @email{mysql@@lists.mysql.com}.
@xref{Bug reports}.
Das @code{mysqlbug} Skript sollte benutzt werden, um Fehlerberichte zu
erzeugen.
@c FIX! RPMs are also binary
Bei Quelltext-Distributionen liegt das @code{mysqlbug} Skript im
@file{scripts} Verzeichnis. Bei Binärdistributionen liegt @code{mysqlbug}
im @file{bin} Verzeichnis. Wenn Sie einen empfindlichen Sicherheits-Bug in
MySQL gefunden haben, sollten Sie eine E-Mail an
@email{security@@mysql.com} schicken.

@cindex Fehler, berichten
@cindex Berichten, Fehler
@cindex Mailing-Listen-Adresse
@cindex @code{mysqlbug}-Skript, Speicherort




@node Deutsch, Installing, Introduction, Top
@c German node <no English equivalent>
@chapter Vorbemerkungen zum deutschen Handbuch

Die Übersetzung einer so umfangreichen technischen Dokumentation wie des
MySQL-Referenzhandbuchs ist schon eine besondere Herausforderung.
Zumindest für jemanden, der seine Zielsprache ernst nimmt:

@itemize @bullet
@item
In diesem Handbuch wird nicht geupdated, sondern aktualisiert.
@item
Eine MySQL-Distribution wird nicht gedownloaded, sondern herunter
geladen.
@item
Und Transaktionen werden nicht gerollbackt, sondern zurückgerollt.
@end itemize

Womit wir auch schon bei der besonderen Herausforderung wären: Jeder,
der sich mit Transaktionen auskennt, weiß, dass beim Fehlschlagen einer
solchen ein Rollback-Befehl ausgeführt wird. Dieses Hauptwort ins
Deutsche zu übersetzen, würde zum Verständnis wenig beitragen - im
Gegenteil.

Damit bleiben alle technischen Fachbegriffe, die sich so und nicht
anders etabliert haben, englisch:

@itemize @bullet
@item
Ein SQL-Statement wird nicht als "Erklärung in der Strukturierten
AbfrageSprache (SAS)" übersetzt.
@item
Abkürzungen wie TCP/IP werden nicht zu ÜSP/ZP
(ÜbertragungsSteuerungsProtokoll/ZwischennetzProtokoll).
@item
Ein Client bleibt ein Client, und ein Server ein Server.
@end itemize

Die Fallstricke einer Übersetzung stecken allerdings in den Details:

@itemize @bullet
@item
Jeder SQL-Kenner weiß, was eine "query" ist. In diesem Handbuch ist
das eine Anfrage.
@item
Gibt es Probleme bei der Übermittlung einer Anfrage, kann es sein,
dass eine Zeitüberschreitung eintritt. Der Profi hätte wahrscheinlich
nach "Timeout" gesucht.
@item
Manche Dinge sind einfacher: Ein "string" ist eine Zeichenkette
(obwohl für Profis vielleicht ungewohnt), ein "hex value" ein
hexadezimaler Wert.
@end itemize

Richtig spannend wird die Übersetzung bei Wörtern, die in der deutschen
Fachsprache zumeist englisch verwendet werden, obwohl es passende
deutsche Entsprechungen gibt:

@itemize @bullet
@item
Im Hauptspeicher ("RAM") zwischengespeicherte Daten werden auf die
Festplatte zurückgeschrieben. Im Englischen heißt das "flushed to
disk", und im Deutschen werden die Daten häufig "geflushed".
@item
Daten werden zwischengespeichert ("gecached").
@item
Speicher wird zugewiesen. Man kann auch "alloziert" sagen, was dem
englischen "allocated" näher kommt.
@end itemize

Alle diese Entsprechungen, bei denen die deutsche Sprache eher in
Vergessenheit geraten ist, wurden zweisprachig aufgenommen. Beispiele:

@itemize @bullet
@item
Alle Daten werden zwischen Anfragen auf die Festplatte zurück
geschrieben (flush).
@item
Aktualisieren Sie (Update), wenn alles in Ordnung ist.
@item
Auf eine höhere Version von MySQL aktualisieren (Upgrade) ...
@end itemize

Gelegentlich wird auch in diesem Handbuch die "Performance getuned",
neue "Features" eines MySQL-"Release" werden beschrieben usw. Anregungen
für eine weiter gehende Eindeutschung nimmt der Übersetzer gern
entgegen. Insbesondere gilt das auch für Hinweise zur Verkürzung
deutscher Ausdrücke. Beispielsweise heißt "case sensitive" (14
Buchstaben) im Handbuch "abhängig von der verwendeten
Groß-/Kleinschreibung" (44 Buchstaben).

Letzter Punkt: Die Übersetzung erfolgte in äußerst enger Anlehnung an
das englischsprachige Original. Nichts wurde hinzugefügt (ausser diesem
Vorwort), geändert oder weggelassen (Ausnahme: die Geschichte der
Änderungen (ChangeLog) vor Version 3.23). Es liegt in der Natur der
Dinge, dass weder Original noch Übersetzung frei von Fehlern sind
(obwohl wir das anstreben). Berichten Sie bitte Übersetzungsfehler,
stilistische "Bugs", die das Verständnis beeinträchtigen und sonstige
Anmerkungen zur Übersetzung direkt an:

@c German FIX added escape @@ in e-mail address.
Stefan Hinz, @email{handbuch@@mysql.com}

Berlin, im Februar 2002

Stefan Hinz, @uref{http://iConnect.de,iConnect GmbH Berlin}


@menu
* Manual-info::                 
* What-is::                     
* What is MySQL AB::            
* Licensing and Support::       
* MySQL 4.0 In A Nutshell::     
* MySQL Information Sources::   
* Compatibility::               
* TODO::                        
* Comparisons::                 
@end menu

@node Manual-info, What-is, Deutsch, Deutsch
@c German node Handbuch-Informationen
@section Über dieses Handbuch

@cindex Speicherort des Online-Handbuchs
@cindex Handbuch, Online-Speicherort

Das ist ein Referenzhandbuch. Es enthält keine allgemeinen Anleitungen zu
SQL oder relationalen Datenbankkonzepten.
@c German FIX these references don't exist:
@c Wenn Sie allgemeine Informationen über SQL suchen,
@c finden Sie diese hier: @ref{SQL allgemein}.
@c Bücher, die sich speziell mit MySQL beschäftigen,
@c finden Sie hier: @ref{MySQL-Bücher}.

Da die MySQL Datenbank Software eine laufende Weiterentwicklung erfährt, wird
das Handbuch regelmäßig aktualisiert.
Die jeweils aktuellste Version dieses Handbuchs befindet sich unter
@uref{http://www.mysql.com/documentation/}.
Dieses Handbuch ist gegenwärtig verfügbar in Texinfo, als Klartext
(plain text), Info, HTML, PostScript und PDF. Das Primärdokument ist die
Texinfo-Datei.
Die HTML-Version wird automatisch produziert, indem eine modifizierte
Version von @code{texi2html} benutzt wird. Die Klartext- und Info-
Versionen werden mit @code{makeinfo} hergestellt. Die PostScript-Version
wird mit @code{texi2dvi} und @code{dvips} produziert. Die PDF-Version
wird mit @code{pdftex} hergestellt.

Wenn Sie Schwierigkeiten haben, Informationen zu finden, beachten Sie bitte
auch die durchsuchbare PHP Version des Handbuchs unter
@uref{http://www.mysql.com/doc/}.

Wenn Sie Vorschläge für Hinzufügungen oder Korrekturen dieses Handbuchs
haben, schicken Sie sie bitte an das Handbuch-Team:
@email{docs@@mysql.com}.

@cindex Handbuch, verfügbare Formate
@cindex Texinfo

Dieses Handbuch wurde geschrieben und wird gewartet von David Axmark,
Michael (Monty) Widenius, Jeremy Cole, und Paul DuBois. Andere
Kontributoren sind unter @ref{Credits} aufgelistet.
Die deutsche Übersetzung stammt von Stefan Hinz. Für die
Aktualität ist Jan Lehnardt zuständig.

Das Copyright (2002) für dieses  liegt bei der schwedischen Firma
@code{MySQL AB}. @xref{Copyright}.


@menu
* Manual conventions::          
@end menu

@node Manual conventions,  , Manual-info, Manual-info
@c German node Handbuch-Konventionen
@subsection Konventionen in diesem Handbuch

Dieses Handbuch benutzt bestimmte typographische Konventionen:

@cindex Handbuch, typografische Konventionen
@cindex Typografische Konventionen
@cindex Konventionen, typografische

@table @asis
@item @code{constant}
Schriftart gleicher Breite (nicht-proportionale Schrift) wird für
Befehle und Optionen benutzt, für SQL-Statements, Datenbank-, Tabellen-
und Spaltennamen, für C- und PERL-Code und für Umgebungsvariablen.
Beispiel: ``Um festzustellen, wie @code{mysqladmin} funktioniert, rufen
Sie den Befehl mit der @code{--help} Option auf.''

@item @file{filename}
Schriftart gleicher Breite, die von Anführungszeichen umgeben ist, wird
für Datei- und Pfadnamen benutzt. Beispiel: ``Die Distribution wird im
Verzeichnis @file{/usr/local/} installiert.''

@item @samp{c}
Schriftart gleicher Breite, die von Anführungszeichen umgeben ist, wird
auch benutzt um Zeichenfolgen anzuzeigen. Beispiel: ``Um ein
Platzhalterzeichen einzugeben, benutzen Sie das @samp{%} Zeichen.''

@item @emph{italic}
Kursivschrift wird für Hervorhebungen verwendet, @emph{wie in diesem
Beispiel}.

@item @strong{boldface}
Fettschrift wird für Namen von Zugriffsrechten verwendet (zum Beispiel:
``Gewähren Sie das @strong{process} Zugriffsrecht nicht leichtfertig'')
und gelegentlich, um @strong{besonders starke Hervorhebungen} zu kennzeichnen.
@end table

Wenn Befehle gezeigt werden, die durch ein bestimmtes Programm
ausgeführt werden sollen, wird dieses Programm durch einen Prompt
(Eingabeaufforderung) vor dem Befehl angezeigt. Der @code{shell>} Prompt
zum Beispiel zeigt an, dass Sie den Befehl von Ihrer Login-Shell aus
ausführen sollen. @code{mysql>} zeigt an, dass Sie den Befehl vom
@code{mysql} Client-Programm aus ausführen sollen:

@example
shell> geben sie hier ein shell-kommando ein
mysql> geben sie hier ein mysql-kommando ein
@end example

Shell-Befehle werden mit der Bourne-Shell-Syntax dargestellt. Wenn Sie
eine @code{csh}-Shell benutzen, müssen die Befehle evtl. etwas anders
eingegeben werden. Das folgende Beispiel zeigt, wie mit der Bourne-Shell eine
Umgebungsvariable gesetzt wird und anschließend ein Befehl abgesetzt
wird:

@example
shell> VARNAME=wert irgendein_befehl
@end example

@cindex Shell-Syntax
@cindex Befehlssyntax

Um @code{csh} auszuführen, würden Sie folgende Sequenz ausführen:

@example
shell> setenv VARNAME wert
shell> irgendein_befehl
@end example

Oft müssen Datenbank-, Tabellen- und Spaltennamen in konkreten Befehlen
ersetzt werden. Um anzuzeigen, dass eine solche Ersetzung notwendig ist,
benutzt dieses Handbuch @code{db_name}, @code{tbl_name} und
@code{col_name}. Sie könnten zum Beispiel folgendes Statement sehen:

@example
mysql> SELECT spalten_name FROM datenbank_name.tabellen_name;
@end example

Wenn Sie ein ähnliches Statement eingeben wollen, müssen Sie Ihre
eigenen Datenbank-, Tabellen- und Spaltennamen eingeben, zum Beispiel
wie folgt:

@example
mysql> SELECT autor_name FROM bibliothek.autorenliste;
@end example

SQL-Statements können in Groß- und Kleinschreibung geschrieben werden.
Wenn dieses Handbuch SQL-Statements darstellt, wird Großschreibung
verwendet, um spezielle Schlüsselworte in diesem Kontext hervorzuheben.
Kleinschreibung wird für den Rest des Statements verwendet. Folgendes
könnten Sie im Kontext des @code{SELECT} Statements sehen:

@example
mysql> SELECT count(*) FROM tabellen_name;
@end example

Im Kontext der @code{COUNT()} Funktion hingegen könnte dasselbe
Statement wie folgt geschrieben werden:

@example
mysql> select COUNT(*) from tabellen_name;
@end example

Wenn keine besondere Hervorhebung beabsichtigt wird, werden alle
Schlüsselworte in Großschreibung dargestellt.

In Syntax-Beschreibungen werden eckige Klammern (@samp{[} und @samp{]})
benutzt, um wahlfrei (optionale) Wörter oder Klauseln anzuzeigen:

@example
DROP TABLE [IF EXISTS] tabellen_name
@end example

Wenn ein Syntaxelement aus einer Anzahl von Alternativen besteht, werden
die Alternativen durch gerade Striche (@samp{|}) voneinander getrennt.
Wenn genau ein Element aus einer Anzahl von Möglichkeiten ausgewählt
werden (@strong{kann}), werden die Alternativen mit eckigen Klammern
aufgelistet (@samp{[} und @samp{]}):

@example
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
@end example

Wenn genau ein Element aus einer Anzahl von Möglichkeiten ausgewählt
werden @strong{muss}, werden die Alternativen innerhalb geschweifter
Klammern aufgelistet (@samp{@{} und @samp{@}}):

@example
@{DESCRIBE | DESC@} tbl_name @{col_name | wild@}
@end example


@node What-is, What is MySQL AB, Manual-info, Deutsch
@c German node Was ist MySQL?
@section Was ist MySQL?

@cindex MySQL, Definition
@cindex MySQL, Einführung


MySQL, die populärste Open Source SQL-Datenbank, wird von MySQL AB zur
Verfügung gestellt. MySQL AB ist ein kommerzielles Unternehmen, dessen
Geschäft darin besteht, Serviceleistungen rund um die MySQL-Datenbank
zur Verfügung zu stellen. @xref{What is MySQL AB}.

@table @asis

@item MySQL ist ein Datenbank-Managementsystem.

Eine Datenbank ist eine strukturierte Sammlung von Daten. Das kann alles
sein - von einer einfachen Einkaufsliste über eine Bildergalerie bis zu
riesigen Informationsmengen in einem Unternehmensnetzwerk. Um Daten zu
einer Computer-Datenbank hinzuzufügen, auf sie zuzugreifen und sie zu
verarbeiten, benötigen Sie ein Datenbank-Managementsystem wie MySQL. Weil
Computer sehr gut darin sind, große Datenmengen zu handhaben, spielt
Datenbank-Management eine zentrale Rolle im Computer-Bereich, sowohl bei
Anwendungen, die allein laufen (Stand-Alone-Utilities) als auch als Teil
anderer Anwendungen.
@cindex Datenbanken, Definition

@item MySQL ist ein relationales Datenbank-Managementsystem.

Eine relationale Datenbank speichert Daten in separaten Tabellen,
anstatt sie alle in einem einzigen großen Speicherraum unterzubringen.
Hierdurch werden hohe Geschwindigkeit und Flexibilität erreicht. Die
Tabellen werden durch definierte Beziehungen verbunden (Relationen), was
es möglich macht, Daten aus verschiedenen Tabellen auf Nachfrage zu
kombinieren. Der SQL-Teil von MySQL steht für "Structured Query
Language" (strukturierte Abfragesprache) - die verbreitetste
standardisierte Sprache für Datenbankzugriffe.

@cindex Relationale Datenbanken, Definition
@cindex SQL, Definition
@item MySQL ist Open-Source-Software.

Open Source bedeutet, dass es für jeden möglich ist, solche Software zu
benutzen und zu verändern. Jeder kann MySQL aus dem Internet herunter
laden und benutzen, ohne irgend etwas zu bezahlen. Jeder, der daran
interessiert ist, kann den Quelltext studieren und den eigenen
Bedürfnissen entsprechend verändern. MySQL benutzt die GPL (GNU
General Public License) @uref{http://www.gnu.org}, um festzulegen, was
Sie mit der Software tun dürfen und was Sie nicht tun dürfen, abhängig
von unterschiedlichen Situationen. Wenn Ihnen die GPL Probleme bereitet
oder wenn Sie MySQL in eine kommerzielle Anwendung einbetten müssen,
können Sie eine kommerziell lizensierte Version von uns erwerben.

@cindex Open Source, Definition
@cindex General Public License

@item Warum sollten Sie MySQL benutzen?

MySQL ist sehr schnell, zuverlässig und leicht zu benutzen. Wenn Sie
nach diesen Eigenschaften suchen, sollten Sie MySQL ausprobieren. MySQL
besitzt eine ganze Reihe praktischer Features, die in enger Kooperation
mit unseren Benutzern entwickelt wurden. Einen Performance-Vergleich
zwischen MySQL und einigen anderen Datenbank-Managementsystemen finden
Sie auf unserer Benchmark-Seite.
@xref{MySQL Benchmarks}.

MySQL wurde ursprünglich entwickelt, um sehr große Datenbanken
handhaben zu können, und zwar sehr viel schneller als existierende
Lösungen. Es wurde mehrere Jahre in höchst anspruchsvollen
Produktionsumgebungen eingesetzt. Heutzutage bietet MySQL eine 
umfangreiche Reihe sehr nützlicher Funktionen. Connectivity,
Geschwindigkeit und Sicherheit machen MySQL äußerst geeignet, um auf
Datenbanken über das Internet zuzugreifen.

@item Die technischen Features von MySQL

Weiter führende technische Informationen finden Sie unter
@ref{Reference}.  MySQL ist ein Client-Server-System, das aus einem
multi-thread SQL-Server besteht, der unterschiedliche Backends,
verschiedene Client-Programme und -Bibliotheken, Verwaltungswerkzeuge
und etliche Programmschnittstellen unterstützt.

Wir stellen MySQL auch als multi-thread Bibliothek zur Verfügung, die
Sie mit Ihren Anwendungen verknüpfen können, um ein kleineres,
schnelleres und leichter zu bedienendes Produkt zu erhalten.

@item MySQL stellt beigesteuerte (contributed) Software in großer Menge
zur Verfügung.

Es ist sehr wahrscheinlich, dass Ihre Lieblingsanwendung oder -sprache
bereits MySQL unterstützt.

@end table

@cindex Aussprache, MySQL
@cindex MySQL, Aussprache
@cindex Ziele von MySQL
Offiziell wird MySQL 'Mai Ess Ku Ell' ausgesprochen (nicht 'Mai
Siekwel'). Wir vermeiden allerdings, Leute zu korrigieren, die
Mai-Siekwel sagen.

@cindex MySQL-Geschichte
@cindex Geschichte von MySQL
@cindex MySQL, Name
@cindex My, Ursprung

Wir fingen ursprünglich mit der Intention an, den @code{mSQL}-Code zu
benutzen, um unsere eigenen Tabellen anzusprechen, wobei wir unsere
eigenen schnellen Low-Level-Routinen (ISAM) benutzten. Nach einigem
Testen gelangten wir allerdings zur Überzeugung, dass @code{mSQL} weder
schnell noch flexibel genug wäre, um unsere Anforderungen abzudecken.
Dies resultierte in einer neuen SQL-Schnittstelle zu unserer Datenbank,
allerdings mit fast derselben API-Schnittstelle, wie sie @code{mSQL}
benutzt. Diese API wurde gewählt, weil sie es erlaubte, Code von
Drittanbietern einfach zu portieren. Die Entstehung des Namens MySQL ist
nicht völlig geklärt. Unser Basis-Verzeichnis und eine große Anzahl
unserer Bibliotheken und Werkzeuge hatten immer schon das Präfix ``my''
während mehr als 10 Jahren. Wie auch immer, auch Montys Tochter (einige
Jahre jünger) heißt My. Welcher der beiden Umstände MySQL den Namen
gab, ist immer noch ein Rätsel, sogar für uns.


@menu
* Features::                    
* Stability::                   
* Table size::                  
* Year 2000 compliance::        
@end menu

@node Features, Stability, What-is, What-is
@c German node Features
@subsection Die wichtigsten Features von MySQL

@cindex Haupt-Features von MySQL
@cindex Features von MySQL

Die folgende Liste beschreibt einige wichtige Charakteristika von MySQL:

@c This list is too technical und should be divided into one feature
@c list comparable to commercial competition und a very technical on
@c with max limits (from crash-me) und so on.
@itemize @bullet
@item
Voll multi-thread unter Benutzung von Kernel-Threads. Das bedeutet, dass
Sie sehr einfach mehrere Prozessoren benutzen können, falls verfügbar.

@item
C-, C++-, Eiffel-, Java-, Perl-, PHP-, Python- und Tcl-APIs. @xref{Clients}.

@item
Läuft auf vielen verschiedenen Plattformen.  @xref{Which OS}.

@item
Viele Spaltentypen: vorzeichenbehaftete / vorzeichenlose Ganzzahlen
(Integer), die 1, 2, 3, 4 und 8 Byte lang sind, @code{FLOAT},
@code{DOUBLE}, @code{CHAR}, @code{VARCHAR}, @code{TEXT}, @code{BLOB},
@code{DATE}, @code{TIME}, @code{DATETIME}, @code{TIMESTAMP},
@code{YEAR}, @code{SET}, und @code{ENUM} Typen.
@xref{Column types}.

@item
Sehr schnelle Joins durch Benutzung eines optimierten Multi-Joins in
einem Durchgang (one-sweep multi-join).

@item
Volle Operator- und Funktionsunterstützung in @code{SELECT}- und
@code{WHERE}-Teilen von Anfragen. Beispiel:

@example
mysql> SELECT CONCAT(vorname, " ", nachname) FROM tabellen_name
           WHERE einkommen/dependents > 10000 AND age > 30;
@end example

@item
SQL-Funktionen sind durch eine hoch optimierte Klassenbibliothek
implementiert und sollten so schnell sein, wie es geht! Üblicherweise
gibt es überhaupt keine Speicherzuordnung (memory allocation) nach der
Initialisierung von Anfragen.

@item
Volle Unterstützung für SQL-@code{GROUP BY} und @code{ORDER BY}-
Klauseln. Unterstützung für Gruppierungsfunktionen (@code{COUNT()},
@code{COUNT(DISTINCT ...)}, @code{AVG()}, @code{STD()}, @code{SUM()},
@code{MAX()} und @code{MIN()}).

@item
Unterstützung für @code{LEFT OUTER JOIN} und @code{RIGHT OUTER JOIN} mit
ANSI-SQL und ODBC-Syntax.

@item
Sie können Tabellen aus unterschiedlichen Datenbanken in ein und
derselben SQL-Anfrage benutzen (ab Version 3.22).

@item
Ein System von Zugriffsberechtigungen und Passwörtern, das sehr flexibel
und sicher ist, und das Host-basierende Verifizierung erlaubt.
Passwörter sind sicher, weil jeder Passwort-Verkehr verschlüsselt wird,
wenn Sie sich mit einem Server verbinden.

@item
ODBC (Open-DataBase-Connectivity) Unterstützung für Win32 (mit
Quelltext). Alle ODBC 2.5 Funktionen und viele weitere. Sie können zum
Beispiel MS Access benutzen, um sich mit Ihrem MySQL-Server zu
verbinden. @xref{ODBC}.

@item
Sehr schnelle B-tree disk Tabellen mit Index-Kompression.

@item
Bis zu 32 Indexe pro Tabelle erlaubt. Jeder Index kann aus 1 bis 16
Spalten oder Teilen von Spalten bestehen. Die maximale Indexlänge
beträgt 500 Bytes (das ändert sich evtl., wenn MySQL kompiliert wird).
Ein Index kann das Präfix eines @code{CHAR}- oder @code{VARCHAR}-Felds
benutzen.

@item
Datensätze fester und variabler Länge.

@item
Im Arbeitsspeicher gehaltene Hash-Tabellen, die als temporäre Tabellen
benutzt werden.

@item
Kann große Datenbanken handhaben. Wir selbst benutzen MySQL bei einigen
Datenbanken, die 50 Mio. Datensätze haben und wir kennen Benutzer, die
MySQL mit 60.000 Tabellen und etwa 5 Milliarden Zeilen benutzen.

@item
Alle Spalten können Vorgabewerte (Defaults) haben. Sie können @code{INSERT}
benutzen, um eine Untermenge der Tabellenspalten mit Werten zu
bestücken. Diejenigen Spalten, die nicht explizit angesprochen werden,
werden auf ihre Vorgabewerte gesetzt.

@item
Benutzt GNU Automake, Autoconf und Libtool aus Portabilitätsgründen.

@item
Geschrieben in C und C++. Getestet mit großen Anzahl verschiedener
Compiler.

@item
Ein sehr schnelles Thread-basierendes Speicherzuordnungs-System (memory
allocation system).

@item
Keine Speicherlecks (memory leaks).  MySQL wurde mit Purify getestet,
einem kommerziellen Werkzeug zur Entdeckung von Speicherlecks.

@item
Beinhaltet @code{myisamchk}, ein sehr schnelles Dienstprogramm zur Überprüfung,
Optimierung und Reparatur von Tabellen. Die gesamte Funktionalität von
@code{myisamchk} steht auch über die SQL-Schnittstelle zur Verfügung.
@xref{MySQL Database Administration}.

@item
Volle Unterstützung für mehrere unterschiedliche Zeichensätze, incl. ISO-
8859-1 (Latin1), big5, ujis und weitere. So sind zum Beispiel die
skandinavischen Zeichen `@ringaccent{a}', `@"a' und `@"o' in Tabellen-
und Spaltennamen erlaubt.

@item
Alle Daten werden mit dem ausgewählten Zeichensatz gespeichert. Alle
Vergleiche für normale Zeichenkettenvergleiche sind unabhängig von
Groß- und Kleinschreibung.

@item
Die Sortierung ist abhängig vom gewählten Zeichensatz (schwedisch als
Vorgabe). Das kann beim Start des MySQL-Servers geändert werden. Um
beispielsweise eine sehr fortgeschrittene Sortierung zu sehen, sehen Sie
sich den tschechischen Sortier-Code an. MySQL unterstützt viele
unterschiedliche Zeichensätze, die bei der Kompilierung und während der
Laufzeit festgelegt werden können. Der neue Zeichensatz 'latin_de' sorgt
für eine korrekte deutsche Sortierreihenfolge.

@item
Aliase auf Tabellen und Spalten sind erlaubt, wie im SQL92-Standard
festgelegt.

@item
@code{DELETE}, @code{INSERT}, @code{REPLACE} und @code{UPDATE} geben die
Anzahl der Zeilen zurück, die geändert wurden (bzw. betroffen sind). Es
ist statt dessen auch möglich, die Anzahl der übereinstimmenden Zeilen
zurückzugeben, indem beim Verbindungsstart zum Server ein entsprechendes
Flag gesetzt wird.

@item
Funktionsnamen kollidieren nicht mit Tabellen- oder Spaltennamen.
@code{ABS} zum Beispiel ist ein gültiger Spaltenname. Die einzige
Einschränkung besteht drin, dass in einem Funktionsaufruf keine
Leerzeichen zwischen Funktionsname und der öffnenden runden Klammer, die
diesem folgt @samp{(}, erlaubt ist. @xref{Reserved words}.

@item
Alle MySQL-Programme können mit der @code{--help} oder @code{-?} Option
aufgerufen werden, um Online-Hilfe zu erhalten.

@item
Der Server kann Clients Fehlermeldungen in verschiedenen Sprachen zur
Verfügung stellen.
@xref{Languages}.

@item
Clients können sich mit dem MySQL-Server über TCP/IP Sockets,
Unix Sockets (Unix) oder Named Pipes (NT) verbinden.

@item
Der MySQL-spezifische @code{SHOW}-Befehl kann benutzt werden, um
Informationen über Datenbanken, Tabellen und Indexe zu erhalten. Der
@code{EXPLAIN}-Code kann benutzt werden um festzustellen, wie der
Optimierer eine Anfrage auflöst.
@end itemize


@node Stability, Table size, Features, What-is
@c German node Stabilität
@subsection Wie stabil ist MySQL?

@cindex Stabilität

Dieser Abschnitt beschäftigt sich mit den Fragen ``Wie stabil ist
MySQL?'' und ``Kann ich mich auf MySQL bei diesem Projekt verlassen?''
Wir werden versuchen, einige Dinge klar zu stellen und einige der
wichtigeren Fragen zu beantworten, die offensichtlich viele Leute
beschäftigen. Dieser Abschnitt wurde aus Informationen zusammen
gestellt, die aus der Mailing-Liste gesammelt wurden (die sehr aktiv
beim Berichten von Bugs ist).

Bei TcX funktioniert MySQL ohne jegliche Probleme in unseren Projekten
seit Mitte 1996. Als MySQL einer breiteren Öffentlichkeit zugänglich
gemacht wurde, fiel uns auf, dass es einige Teile von ``ungetestetem
Code'' gab, die schnell von neuen Benutzern gefunden wurden, die
Anfragen machten, die von unseren eigenen abwichen. Seitdem hat jedes
neue Release weniger Portabilitätsprobleme als das vorhergehende (obwohl
jedes viele neue Features hat).

Jedes Release von MySQL war benutzbar. Probleme gab es nur, wenn
Benutzer anfingen, Code aus den ``Grauzonen'' zu benutzen. Natürlich
wissen Benutzer von ausserhalb nicht, was diese Grauzonen sind, daher
versucht dieser Abschnitt, die momentan bekannten aufzuzeigen. Die
Beschreibungen hier beziehen sich auf Version 3.23 von MySQL. Alle
bekannten und berichteten Bugs werden in der letzten Version behoben,
mit Ausnahme der Bugs, die im Bugs-Abschnitt aufgelistet sind, was Dinge
sind, die auf das Design zurückzuführen sind. @xref{Bugs}.

MySQL ist in mehrfachen Ebenen (Layers) und verschiedenen unabhängigen
Modulen geschrieben. Diese Module sind im Folgenden aufgeführt, wobei
angezeigt wird, wie gut getestet jedes von ihnen ist:

@cindex Module, Auflistung

@table @strong
@item Der ISAM Tabellen-Handler --- stabil
Dieser verwaltet Speicherung und Abfrage aller Daten in MySQL Version
3.22 und früher. In allen Releases von MySQL gab es nicht einen einzigen
(berichteten) Bug in diesem Code. Die einzige Möglichkeit, eine
zerstörte (korrumpierte) Tabelle zu erhalten, besteht darin, den Server
mitten während eines Updates zu killen. Selbst dadurch ist es
unwahrscheinlich, dass Daten unwiederbringlich zerstört werden, denn
alle Daten werden zwischen Anfragen auf die Festplatte zurück
geschrieben (flush). Es hat nicht einen einzigen Bug-Bericht gegeben, in
dem von verlorenen Daten aufgrund von MySQL-Bugs berichtet wurde.

@cindex ISAM-Tabellen-Handler
@cindex Speicherung, Daten
@cindex Abfrage, Daten
@cindex Daten, ISAM-Tabellen-Handler

@item Der MyISAM Tabellen-Handler --- stabil
Dieser wurde in MySQL Version 3.23 hinzu gefügt. Er basiert zum großen
Teil auf dem ISAM Tabellen-Code, hat aber eine Menge neuer und sehr
nützlicher Features.

@item Der Parser und lexikalische Analysator --- stabil
Es hat seit sehr langer Zeit keinen einzigen berichteten Bug in diesem
System gegeben.

@item Der C Client-Code --- stabil
Keine bekannten Probleme. Im frühen 3.20 Release gab es einige
Einschränkungen hinsichtlich der Größe des Sende- / Empfangs-Puffers
(buffer size). Ab Version 3.21 ist die Puffergröße jetzt dynamisch, bis
zu einem Vorgabewert von 16 M.

@item Standard-Client-Programme --- stabil
Dies beinhaltet @code{mysql}, @code{mysqladmin}, @code{mysqlshow},
@code{mysqldump} und @code{mysqlimport}.

@item Basis-SQL --- stabil
Die grundlegenden SQL-Funktionen, Zeichenketten-Klassen und dynamisches
Speicher-Handling. Nicht ein einziger berichteter Bug in diesem System.

@item Anfragen-Optimierer (Query optimizer) --- stabil

@item Bereichs-Optimierer (Range optimizer) --- stabil

@item Join-Optimierer (Join optimizer) --- stabil

@item Sperren (Locking) --- Gamma
Dies ist sehr system-abhängig. Auf einigen Systemen gibt es große
Probleme, wenn Standard-Betriebssystem-Sperren verwendet wird
(@code{fcntl()}). In solchen Fällen sollten Sie den MySQL-Daemon mit dem
Flag @code{--skip-locking} laufen lassen. Bekannt ist, dass solche
Probleme auf manchen Linux-Systemen vorkommen sowie auf SunOS, wenn NFS-
gemountete Dateisysteme verwendet werden.

@item Linux-Threads --- stabil
Das hauptsächliche Problem fand sich im @code{fcntl()}-Aufruf, der durch
Benutzung der @w{@code{--skip-locking}}-Option bei @code{mysqld} behoben
werden kann. Einige Leute haben Lockup-Probleme mit Version 0.5
berichtet. Linux-Threads müssen rekompiliert werden, wenn Sie mehr als
1000 gleichzeitige Verbindungen benutzen wollen. Obwohl es möglich ist,
so viele Verbindungen mit den vorgabemäßigen Linux-Threads laufen zu
lassen (obwohl man nie über 1021 kommen wird), macht das vorgabemäßige
Stack-Spacing von 2 MB die Applikation unstabil, und wir konnten einen
Coredump reproduzieren, nachdem 1021 Verbindungen im Leerlauf (idle
connections) hergestellt wurden. @xref{Linux}.

@item Solaris 2.5+ pthreads --- stabil
Wir benutzen dies für unsere gesamte Produktionsarbeit.

@item MIT-pthreads (andere Systeme) --- stabil
Seit Version 3.20.15 gab es keine berichteten Bugs mehr, und keine
bekannten Bugs seit Version 3.20.16. Auf einigen Systemen gibt es ein
``Misfeature'', das heißt einige Operationen sind recht langsam (1/20
Sekunde Schlafzyklus zwischen jeder Anfrage). Natürlich können MIT-
Threads alles ein bisschen verlangsamen, aber Index-basierende
@code{SELECT}-Statements werden üblicherweise in einem Zeit-Frame
ausgeführt, also sollte es kein mutex locking/thread juggling geben.

@item Andere Thread-Implementierungen --- Beta - Gamma
Die Ports zu anderen Systemen sind noch sehr neu und können Bugs haben,
möglicherweise auch in MySQL, aber in den meisten Fällen in der Thread-
Implementierung selbst.

@item @code{LOAD DATA ...}, @code{INSERT ... SELECT} --- stabil
Einige Leute dachten, hier Bugs gefunden zu haben, aber üblicherweise
haben sich diese als Missverständnisse heraus gestellt. Bitte sehen Sie
zuerst im Handbuch nach, bevor Sie Bugs berichten!

@item @code{ALTER TABLE} --- stabil
Einige Änderungen in Version 3.22.12.

@item DBD --- stabil
Wird jetzt von Jochen Wiedmann gewartet
(@email{wiedmann@@neckar-alb.de}).  Danke!

@item @code{mysqlaccess} --- stabil
Geschrieben und gewartet von Yves Carlier 
(@email{Yves.Carlier@@rug.ac.be}). Danke!

@item @code{GRANT} --- stabil
große Änderungen in MySQL Version 3.22.12.

@item @strong{MyODBC} (benutzt ODBC SDK 2.5) --- Gamma
Scheint mit einigen Programmen gut zu laufen.

@item Replikation -- Beta / Gamma
Wir arbeiten noch an der Replikation, also erwarten Sie nicht, dass
diese schon felsenfest steht. Auf der anderen Seite benutzen MySQL-
Benutzer diese bereits mit guten Resultaten.

@item BDB-Tabellen -- Beta
Der Berkeley-Datenbank-Code ist sehr stabil, aber wir verbessern immer
noch die Schnittstelle zwischen MySQL und BDB-Tabellen, also wird es
einige Zeit dauern, bevor dies so gut wie andere Tabellentypen getestet
ist.

@item InnoDB-Tabellen -- Beta
Diese wurden @code{MySQL} kürzlich hinzu gefügt. Sie scheinen gut zu
funktionieren und können nach einigen anfänglichen Tests benutzt werden.

@item Automatische Wiederherstellung von MyISAM-Tabellen - Beta
Dies betrifft nur den neuen Code, der beim Öffnen einer Tabelle
nachsieht, ob diese korrekt geschlossen wurde und ein automatisches
Überprüfen / Reparieren der Tabelle ausführt, falls das nicht der Fall
war.

@item MERGE-Tabellen -- Beta / Gamma
Die Benutzung von Schlüsseln bei @code{MERGE}-Tabellen ist noch nicht
sehr ausgetestet. Der restliche Teile des @code{MERGE}-Codes ist recht
gut getestet.

@item FULLTEXT -- Beta
Textsuche scheint zu funktionieren, wird aber noch nicht viel
eingesetzt.

@end table

MySQL AB stellt E-Mail-Support für zahlende Kunden bereit, aber die
MySQL-Mailingliste bietet üblicher Weise Antworten für die meisten
Fragen. Bugs werden meist direkt mit einem Patch behoben; für
schwerwiegende Bugs gibt es fast immer ein neues Release.


@node Table size, Year 2000 compliance, Stability, What-is
@c German node Tabellengröße
@subsection Wie groß können MySQL-Tabellen sein?

@cindex Tabellen, maximale Größe
@cindex Größe von Tabellen
@cindex Betriebssysteme, Dateigrößen-Beschränkungen
@cindex Beschränkungen, Dateigröße
@cindex Dateien, Dateigröße

MySQL Version 3.22 hat eine Begrenzung auf 4G bei der Tabellengröße.
Mit dem neuen @code{MyISAM} in MySQL Version 3.23 wurde die maximale
Tabellengröße auf 8 Millionen Terabytes (2 ^ 63 bytes) hochgeschraubt.

Beachten Sie allerdings, dass Betriebssysteme ihre eigenen Dateigrößen-
Beschränkungen haben. Hier sind einige Beispiele:

@multitable @columnfractions .5 .5
@item @strong{Betriebssystem}   @tab @strong{Dateigrößen-Beschränkung}
@item Linux-Intel 32 bit        @tab 2G, 4G oder mehr, abhängig von der Linux-Version
@item Linux-Alpha               @tab 8T (?)
@item Solaris 2.5.1             @tab 2G (möglich sind 4G mit Patch)
@item Solaris 2.6               @tab 4G
@item Solaris 2.7 Intel         @tab 4G
@item Solaris 2.7 ULTRA-SPARC   @tab 8T (?)
@end multitable

Auf Linux 2.2 kann man größere Tabellen als 2G benutzen, wenn man den
LFS-Patch für das ext2 Dateisystem benutzt. Auf Linux 2.4 existiert
zusätzlich ein Patch für das ReiserFS, um Unterstützung für große
Dateien zu erhalten.

Letztlich wird die Tabellengröße für MySQL normalerweise durch das
Betriebssystem begrenzt.

Vorgabemäßig haben MySQL-Tabellen eine maximale Größe von etwa 4G. Sie
können die maximale Tabellengröße für eine Tabelle mit dem @code{SHOW
TABLE STATUS}-Befehl überprüfen oder mit @code{myisamchk -dv
tabellen_name}. @xref{SHOW}.

Wenn Sie größere Tabellen als 4G benötigen (und Ihr Betriebssystem dies
unterstützt), sollten Sie die @code{AVG_ROW_LENGTH}- und
@code{MAX_ROWS}-Parameter benutzen, wenn Sie Ihre Tabelle anlegen.
@xref{CREATE TABLE}. Sie können diese auch später setzen, mit
@code{ALTER TABLE}. @xref{ALTER TABLE}.

Falls auf Ihre große Tabelle nur mit Lesezugriff zugegriffen wird
(read-only), können Sie auch @code{myisampack} benutzen, um mehrere
Tabellen zu vereinen (merge) und sie zu einer zu komprimieren.
@code{myisampack} komprimiert eine Tabelle üblicherweise mindestens um
50%, also können Sie effektiv viel größere Tabellen benutzen.
@xref{myisampack, ,@code{myisampack}}.

Sie können die Dateibegrenzung des Betriebssystems für @code{MyISAM}
Daten-Dateien umgehen, indem Sie die @code{RAID}-Option benutzen.
@xref{CREATE TABLE}.

Eine weitere Lösung kann die MERGE-Bibliothek darstellen, die Ihnen
erlaubt, eine Sammlung identischer Tabellen zugleich zu benutzen.
@xref{MERGE, MERGE tables}.


@node Year 2000 compliance,  , Table size, What-is
@c German node Jahr-2000-Konformität
@subsection Jahr-2000-Konformität

@cindex Jahr-2000-Konformität
@cindex Kompatibilität, Y2K, Jahr 2000
@cindex Datumsfunktionen, Y2K, Jahr-2000-Konformität

MySQL selbst hat keine Probleme mit der Jahr-2000-Konformität:

@itemize @bullet
@item
MySQL benutzt Unix-Zeitfunktionen und hat keine Probleme mit
Datumsangaben bis @code{2069}. Alle zweistelligen Jahresangaben werden
als Angaben zwischen @code{1970} und @code{2069}, betrachtet, was
bedeutet, dass, wenn Sie @code{01} in einer Spalte speichern, MySQL dies
als @code{2001} behandelt.

@item
Alle MySQL Datumsfunktionen sind in einer Datei @file{sql/time.cc}
gespeichert und sehr sorgfältig kodiert, um Jahr-2000-sicher zu sein.

@item
In MySQL Version 3.22 und später kann der neue Spaltentyp @code{YEAR}
Jahre @code{0} und von @code{1901} bis @code{2155} in 1 Byte speichern
und sie mit 2 oder 4 Ziffern anzeigen.
@end itemize

Probleme können Sie bekommen, wenn Sie MySQL mit Applikationen benutzen,
die MySQL auf eine Art benutzen, die nicht Jahr-2000-sicher ist. Zum
Beispiel speichern oder ändern viele alte Applikationen Jahresangaben,
indem sie zweistellige Werte benutzen (was mehrdeutig ist), anstatt
vierstellige Werte zu nehmen. Dieses Problem kann durch Applikationen
verschlimmert werden, die Werte wie @code{00} oder @code{99} als Anzeiger
``fehlender'' Werte benutzen.

Leider sind diese Probleme möglicherweise schwer zu beheben, weil
verschiedene Applikationen von unterschiedlichen Programmierern
geschrieben sein können, von denen jeder einen anderen Satz von
Konventionen und Funktionen benutzt haben kann, was die Handhabung von
Datumsangaben betrifft.

Hier ist eine einfache Demonstration, die zeigt, dass MySQL keine
Probleme mit Datumsangaben bis zum Jahr 2030 hat:

@example
mysql> DROP TABLE IF EXISTS y2k;
Query OK, 0 rows affected (0.01 sec)

mysql> CREATE TABLE y2k (date date, date_time datetime, time_stamp timestamp);
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO y2k VALUES 
    -> ("1998-12-31","1998-12-31 23:59:59",19981231235959),
    -> ("1999-01-01","1999-01-01 00:00:00",19990101000000),
    -> ("1999-09-09","1999-09-09 23:59:59",19990909235959),
    -> ("2000-01-01","2000-01-01 00:00:00",20000101000000),
    -> ("2000-02-28","2000-02-28 00:00:00",20000228000000),
    -> ("2000-02-29","2000-02-29 00:00:00",20000229000000),
    -> ("2000-03-01","2000-03-01 00:00:00",20000301000000),
    -> ("2000-12-31","2000-12-31 23:59:59",20001231235959),
    -> ("2001-01-01","2001-01-01 00:00:00",20010101000000),
    -> ("2004-12-31","2004-12-31 23:59:59",20041231235959),
    -> ("2005-01-01","2005-01-01 00:00:00",20050101000000),
    -> ("2030-01-01","2030-01-01 00:00:00",20300101000000),
    -> ("2050-01-01","2050-01-01 00:00:00",20500101000000);
Query OK, 13 rows affected (0.01 sec)
Records: 13  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM y2k;
+------------+---------------------+----------------+
| date       | date_time           | time_stamp     |
+------------+---------------------+----------------+
| 1998-12-31 | 1998-12-31 23:59:59 | 19981231235959 |
| 1999-01-01 | 1999-01-01 00:00:00 | 19990101000000 |
| 1999-09-09 | 1999-09-09 23:59:59 | 19990909235959 |
| 2000-01-01 | 2000-01-01 00:00:00 | 20000101000000 |
| 2000-02-28 | 2000-02-28 00:00:00 | 20000228000000 |
| 2000-02-29 | 2000-02-29 00:00:00 | 20000229000000 |
| 2000-03-01 | 2000-03-01 00:00:00 | 20000301000000 |
| 2000-12-31 | 2000-12-31 23:59:59 | 20001231235959 |
| 2001-01-01 | 2001-01-01 00:00:00 | 20010101000000 |
| 2004-12-31 | 2004-12-31 23:59:59 | 20041231235959 |
| 2005-01-01 | 2005-01-01 00:00:00 | 20050101000000 |
| 2030-01-01 | 2030-01-01 00:00:00 | 20300101000000 |
| 2050-01-01 | 2050-01-01 00:00:00 | 00000000000000 |
+------------+---------------------+----------------+
13 rows in set (0.00 sec)

@end example

Das zeigt, dass die @code{DATE}- und @code{DATETIME}-Typen für zukünftige
Datumsangaben keine Probleme bereiten werden (sie handhaben Datumsangaben
bis zum Jahr 9999).

Der @code{TIMESTAMP}-Typ, der zur Speicherung der aktuellen Zeit benutzt
wird, hat nur einen Bereich bis zu @code{2030-01-01}.  @code{TIMESTAMP} hat
einen Bereich von @code{1970} bis @code{2030} auf 32-Bit-Maschinen
(vorzeichenbehafteter Wert). Auf 64-Bit-Maschinen handhabt dieser
Spaltentyp bis zu @code{2106} (vorzeichenloser Wert).

Obwohl MySQL Jahr-2000-kompatibel ist, sind Sie dafür verantwortlich,
mehrdeutige Eingaben zu vermeiden. Siehe @ref{Year 2000 compliance} wegen
der Regeln, die MySQL anwendet, wenn mehrdeutige Datumsangaben gemacht
werden (Datumsangaben, die zweistellige Jahreswerte verwenden).



@node What is MySQL AB, Licensing and Support, What-is, Deutsch
@c German node Was ist MySQL AB?
@section Was ist MySQL AB?

@cindex MySQL AB, Definition

@code{MySQL AB} ist das Unternehmen der MySQL Gründer und Hauptentwickler.
MySQL AB wurde ursprünglich in Schweden von David Axmark, Allan Larsson 
und Michael @code{Monty} Widenius gegründet.

Alle Entwickler des MySQL Servers sind Angestellte dieses Unternehmens.
Wir sind eine virtuelle Firma mit Mitarbeitern, die über die ganze Welt
verstreut in aller Herren Länder sitzen. Der Hauptteil unserer Kommunikation
untereinander, mit unseren Anwendern, Unterstützern und Partnern wird über
das Internet abgewickelt

Wir haben uns der Entwicklung und Verbreitung des MySQL Datenbankservers
verschrieben. MySQL hält das Copyright der MySQL Quelltexte, des MySQL Logos 
und dieses Handbuchs.. @xref{What-is}.


Die MySQL-Kernwerte zeigen unsere Verpflichtung gegenüber MySQL und Open
Source.

Wir wollen, dass MySQL folgendes ist:

@itemize @bullet
@item
Die beste und meist benutzte Datenbank der Welt.
@item
Verfügbar für alle. Alle sollen sich MySQL leisten können.
@item
Leicht zu benutzen.
@item
Kontinuierlich verbessert, trotzdem immer schnell und sicher bleibend.
@item
Es soll Spass machen, MySQL zu benutzen und zu verbessern.
@item
Frei von Bugs.
@end itemize


MySQL AB und die Leute von MySQL AB:

@itemize @bullet
@item
Verbreiten die Open-Source-Philosophie und unterstützen die
Open-Source-Community.
@item
Bemühen sich, gute Bürger zu sein.
@item
Bevorzugen Partner, die unsere Werte und unsere Geisteshaltung teilen.
@item
Beantworten Mail und geben Support.
@item
Sind ein virtuelles Unternehmen, das mit anderen im Netzwerk
zusammenarbeitet (networking).
@item
Arbeiten gegen Software-Patente.
@end itemize

@menu
* MySQL AB business model and services::  
@end menu

@node MySQL AB business model and services,  , What is MySQL AB, What is MySQL AB
@c German node MySQL AB Geschäftsmodell und Services
@subsection Geschäftsmodell und Dienstleistungen von MySQL AB

Eine der uns häufig gestellten Fragen ist: Wie kann man von etwas leben,
das man kostenlos abgibt? Hier ist die Antwort:
MySQL AB verdient Geld mit Support, Dienstleistungen, kommerziellen
Lizenzen und Lizenzgebühren, das wir dazu verwenden, die
Produktentwicklung zu finanzieren und die MySQL-Geschäftsfelder
auszubauen.


Unser Unternehmen läuft seit der Gründung profitabel. Im Oktober 2001
akzeptierten wir eine Risikokapitalfinanzierung durch führende
skandinavische Investoren und eine Handvoll Business-Angels. Die
Investitionen werden genutzt, um unser Geschäftsmodell auf solide Füße
zu stellen und eine Grundlage für nachhaltiges Wachstum zu schaffen.

@menu
* Business Services Support::   
* Business Services Training::  
* Business Services Consulting::  
* Business Services Commercial licenses::  
* Business Services Partnering::  
* Business Services Advertising::  
* Contact information::         
@end menu

@node Business Services Support, Business Services Training, MySQL AB business model and services, MySQL AB business model and services
@c German node Business Services Support
@subsubsection Support

MySQL AB gehört den Gründern und Haupt-Entwicklern der MySQL-Datenbank
und wird von ihnen betrieben. Die Entwickler fühlen sich verpflichtet,
Kunden und anderen Benutzern Support zu bieten, um mit deren
Bedürfnissen und Problemen in Kontakt zu bleiben. Unser gesamter Support
wird durch qualifizierte Entwickler geleistet. Wirklich schwierige
Fragen werden von Michael @code{Monty} Widenius beantwortet, der der
erste Entwickler des MySQL-Servers ist. @xref{Support}.

Um Support unterschiedlicher Grade zu bestellen, besuchen Sie bitte die
Bestellseite unter @uref{https://order.mysql.com/}. Wenn Sie nur
beschränkten Zugriff auf das Internet haben, setzen Sie sich bitte mit
unserem Vertrieb unter @email{sales@@mysql.com} in Verbindung.

@node Business Services Training, Business Services Consulting, Business Services Support, MySQL AB business model and services
@c German node Business Services Training
@subsubsection Training und Zertifizierung

MySQL AB führt Schulungen zu MySQL und verwandten Themen weltweit durch.
Wir bieten sowohl offene Kurse als auch In-house-Trainings an, die auf
die speziellen Bedürfnisse Ihres Unternehmens zugeschnitten sind.
MySQL-Schulungen werden auch durch unsere Partner durchgeführt, die
Authorised MySQL Training Center.

Unsere Schulungsmaterialien benutzen dieselben Beispiel-Datenbanken wie
unsere Dokumentation und unsere Beispiel-Applikationen und werden
ständig aktualisiert, um den Entwicklungsstand der neusten MySQL-Version
widerzuspiegeln. Unsere Trainer erhalten Rückhalt vom Entwicklungsteam,
um die Trainingsqualität und die kontinuierliche Entwicklung des
Schulungsmaterials sicherzustellen. Das stellt auch sicher, dass keine
während der Kurse aufgetretenen Fragen unbeantwortet bleiben.

Wenn Sie an unseren Schulungen teilnehmen, können Sie sicher sein, die
Ziele zu erreichen, die Sie mit Ihren MySQL-bezogenen Applikationen
anstreben. Ausserdem haben Sie folgende Vorteile:

@itemize @bullet
@item
Sie sparen Zeit.
@item
Sie verbessern die Performance Ihrer Applikation(en).
@item
Sie verringern die Notwendigkeit zusätzlicher Hardware, was Kosten
spart.
@item
Sie verbessern Ihre Sicherheit.
@item
Sie erhöhen die Zufriedenheit Ihrer Kunden und Mitarbeiter.
@item
Sie bereiten sich auf die MySQL-Zertifizierung vor.
@end itemize

Wenn Sie an unseren Schulungen Interesse als möglicher Teilnehmer oder
Trainingspartner haben, besuchen Sie bitte die Seite unter
@uref{http://www.mysql.com/training/}. Wenn Sie nur beschränkten Zugriff
auf das Internet haben, setzen Sie sich bitte mit unserem
Trainingspersonal unter @email{training@@mysql.com} in Verbindung.

Die Veröffentlichung des MySQL-Zertifizierungsprogramms ist für 2002
geplant. Details finden Sie unter
@uref{http://www.mysql.com/training/certification.html}. Wenn Sie stets
die neusten Informationen über das MySQL-Zertifizierungsprogramm haben
wollen, schicken Sie bitte eine E-Mail an
@email{certification@@mysql.com}.


@c German FIX this node entry was missing but the section was there...
@node Business Services Consulting, Business Services Commercial licenses, Business Services Training, MySQL AB business model and services
@c German node Business Services Consulting
@subsubsection Beratung
MySQL AB und seine authorisierten Partner bieten Benutzern des
MySQL-Servers und denen, die ihn in ihre Software einbetten wollen,
Beratungsleistungen, weltweit.

Unsere Berater können Ihnen helfen, Ihre Datenbanken zu entwerfen und zu
optimieren, effiziente Anfragen zu konstruieren, Ihre Plattform auf
optimale Performance zu tunen, Migrationsprobleme zu lösen, Replikation
aufzusetzen, robuste transaktionale Applikationen zu bauen und vieles
mehr. Wir helfen auch Kunden dabei, den MySQL-Server für den
Großflächigen Einsatz in ihre Produkte und Applikationen einzubauen.

Unsere Berater arbeiten in enger Kooperation mit unserem
Entwicklungsteam, was die technische Qualität unserer Dienstleistungen
sicherstellt. Beratungsaufgaben erstrecken sich von zweitägigen
Power-Start-Sessions bis zu Projekten, die Wochen und Monate dauern.
Unsere Kompetenz deckt nicht nur den MySQL-Server ab, sondern auch
Programmier- und Skripting-Sprachen wie PHP, Perl und andere.

Wenn Sie an unseren Beratungsleistungen interessiert sind oder ein
Consulting-Partner werden wollen, besuchen Sie bitte unsere Seite unter
@uref{http://www.mysql.com/consulting/}. Wenn Sie nur beschränkten
Zugriff auf das Internet haben, setzen Sie sich bitte mit unserem
Beratungspersonal unter @email{consulting@@mysql.com} in Verbindung.

@node Business Services Commercial licenses, Business Services Partnering, Business Services Consulting, MySQL AB business model and services
@c German node Business Services Commercial Licenses
@subsubsection Kommerzielle Lizenzen

Die MySQL-Datenbank wird unter der @code{GNU General Public License}
veröffentlicht (@code{GPL}). Das bedeutet, dass die MySQL-Software
kostenlos unter der GPL benutzt werden darf. Wenn Sie nicht an die
GPL-Bedingungen gebunden sein wollen (was in der Folge bedeutet, dass
auch Ihre eigenen Applikationen GPL werden), können Sie eine
kommerzielle Lizenz für dasselbe Produkt unter
@uref{https://order.mysql.com/} erwerben.

Weil MySQL AB das Copyright am MySQL-Server besitzt, können wir eine
@code{duale Lizensierung} einsetzen, was heißt, dass dasselbe Produkt
sowohl unter der GPL als auch unter einer kommerziellen Lizenz
erhältlich ist. Das berührt in keiner Weise die Verpflichtung von MySQL
AB gegenüber @code{Open Source}. Wegen Details, wann eine kommerzielle
Lizenz erforderlich ist, sehen Sie bitte unter
@ref{Lizenzpolitik} nach.

Wir verkaufen auch kommerzielle Lizenzen von Open-Source-GPL-Software
Dritter. Ein gutes Beispiel hierfür ist der
@code{InnoDB}-Tabellen-Handler, der ACID-Unterstützung, Sperren auf
Zeilenebene, Wiederherstellung nach Abstürzen, Multiversionierung,
Fremdschlüsselunterstützung und vieles mehr bietet.

@node Business Services Partnering, Business Services Advertising, Business Services Commercial licenses, MySQL AB business model and services
@c German node Business Services Partnering
@subsubsection Partnerprogramme
@cindex Partnerschaft mit MySQL AB

MySQL AB hat ein weltweites Partnerprogramm, dass Schulungskurse,
Support, Beratung, Lösungen, Publikationen plus Weiterverkauf und
Vertrieb von MySQL und verwandten Produkten beinhaltet. Partner
erscheinen unter @uref{http://www.mysql.com/} auf der Website und
erhalten das Recht, spezielle Versionen der MySQL-Schutzmarken zu
benutzen, um ihre Produkte zu identifizieren und ihr Geschäft
voranzutreiben. Wenn Sie interessiert sind, ein MySQL-AB-Partner zu
werden, schicken Sie bitte eine E-Mail an @email{partner@@mysql.com}.

Das Wort @code{MySQL} und das MySQL-Delphin-Logo sind Schutzmarken von
MySQL AB. @xref{MySQL AB Logos and Trademarks}.

@node Business Services Advertising, Contact information, Business Services Partnering, MySQL AB business model and services
@c German node Business Services Advertising
@subsubsection Werbung

Die MySQL-Website (@uref{http://www.mysql.com/}) ist bei Entwicklern und
Benutzern beliebt. Im Oktober 2001 bedienten wir 10 Millionen
Seitenanfragen (PageViews). Unsere Besucher repräsentieren eine Gruppe,
die Kaufentscheidungen und Empfehlungen sowohl für Software als auch für
Hardware trifft. 12% unserer Besucher genehmigen Kaufentscheidungen,
lediglich 9% sind überhaupt nicht an Kaufentscheidungen beteiligt. Mehr
als 65% haben innerhalb des letzten halben Jahres online eingekauft, 70%
planen, in den nächsten Monaten einzukaufen. Wenn Sie Interesse haben,
Werbebanner auf unserer Website @uref{http://www.mysql.com/} zu
schalten, setzen Sie sich bitte mit @email{advertising@@mysql.com} in
Kontakt.

@node Contact information,  , Business Services Advertising, MySQL AB business model and services
@c German node Kontaktinformationen
@subsubsection Kontaktinformationen

@cindex Kontaktinformationen
@cindex Lizensierung, Kontaktinformationen
@cindex Werbung, Kontaktinformationen
@cindex Anstellung, Kontaktinformationen
@cindex Partnerschaft mit MySQL
@cindex Anstellung bei MySQL
@cindex Jobs bei MySQL

Die MySQL Website (@uref{http://www.mysql.com/})
enthält die neusten Informationen über MySQL und MySQL AB.

Für Presseservice und Anfragen aller Art, die in unseren
Veröffentlichungen (@uref{http://www.mysql.com/news/}) nicht
behandelt werden, wenden Sie sich bitte an 
@email{press@@mysql.com}.

Zeitnahe, präzise Antworten auf technische Fragen erhalten Sie, wenn Sie
unter @uref{https://order.mysql.com/, order} einen unserer
@uref{http://www.mysql.com/Support/arrangements/types.html,
Support-Verträge} abschließen.
MySQL-Support wird von den MySQL-Entwicklern geleistet, weshalb der
Standard extrem hoch ist.

Informationen über MySQL Trainig erhalten Sie unter
@uref{http://www.mysql.com/training/}. Wenn Sie einen
eingeschränkten Internetzugang haben, kontaktieren Sie
bitte unser Trainingspersonal unter @email{training@@mysql.com}.
@xref{Business Services Training}.

Für Informationen über das MySQL Zertifizierungsprogramm
erhalten Sie unter @uref{http://www.mysql.com/training/certification.html}.
Wenn Sie weiterhin über das MySQL Zertifizierungsprogramm informiert
werden wollen, schreiben Sie eine E-Mail an @email{certification@@mysql.com}.
@xref{Business Services Consulting}.

Kommerzielle Lizenzen können online unter @uref{https://order.mysql.com/}
abgewickelt werden. Dort finden Sie ausserdem Informationen darüber, 
wie Sie ihre Bestellung per Fax erledigen können. Wenn Sie Fragen bezüglich
der Lizensierung haben, oder Sie ein Angebot über eine größere Lizenzerteilung
erhalten wollen, füllen Sie bitte Das Kontaktformular auf unserer Website
(@uref{http://www.mysql.com/}) aus, oder schicken Sie eine E-Mail
an @email{licensing@@mysql.com} (für Lizenzfragen) oder an
@email{sales@@mysql.com} (für Verkaufsinformationen).
@xref{Lizenzpolitik}.

Wenn Sie daran interessiert sind, ein Werbebanner auf unserer Website
(@uref{http://www.mysql.com/}) zu schalten, schicken Sie bitte 
eine E-Mail an @email{advertising@@mysql.com}.
@xref{Business Services Advertising}.

Wenn Sie ein Unternehmen vertreten, dass an einer Partnerschaft mit MySQL
interessiert ist, schicken Sie bitte eine E-Mail an
@email{partner@@mysql.com}.

Für weitere Informationen über die MySQL Schutzmarkenbestimmungen, beachten
Sie bitte @uref{http://www.mysql.com/company/trademark.html} oder kontaktieren
Sie @email{trademark@@mysql.com}.
@c German FIX changed 'and' to 'und' to make German xref work
@xref{MySQL AB Logos and Trademarks}.

Wenn Sie an einem der Jobs interessiert sind, die im
@uref{http://www.mysql.com/development/jobs/, jobs}-Abschnitt aufgeführt
sind, schicken Sie bitte eine E-Mail an @email{jobs@@mysql.com}. Bitte
senden Sie ihre CV nicht als Anhang an dieser mail mit, sondern
fügen Sie sie lieber am Ende ihrer mail als Klartext (plain text) ein.

Allgemeine Diskussionen mit vielen unserer Benutzer können Sie auf den
entsprechenden @uref{http://www.mysql.com/documentation/lists.html,
Mailing-Listen} führen.

Fehlerberichte (Auch Bugreporte genannt), sowie Fragen und Kommentare, sollten 
an die Mailingliste @email{mysql@@lists.mysql.com} gehen. Wenn Sie
ein empfindliches Sicherheitsloch im MySQL Server gefunden haben, sollten 
@c German FIX added . after schreiben and after the xref.
Sie eine E-Mail an @email{security@@mysql.com} schreiben.
@xref{Bug reports}.

Wenn Sie Benchmarkergebnis haben, die wir veröffentlichen können, kontaktieren
Sie uns unter @email{benchmarks@@mysql.com}.

Wenn Sie Vorschläge für Hinzufügungen oder Korrekturen dieses Handbuchs
haben, schicken Sie sie bitte an das Handbuch-Team:
@email{docs@@mysql.com}.

Fragen zur Arbeitsweise oder zu Inhalten unserer Website(@uref{http://www.mysql.com/})
stellen Sie bitte an @email{webmaster@@mysql.com}.

Fragen über das MySQL Portal (@uref{http://www.mysql.com/portal/})
können an @email{portals@@mysql.com} geschickt werden.

Die Datenschutzbestimmungen von MySQL AB können Sie unter 
@uref{http://www.mysql.com/company/privacy.html} einsehen.
Für irgendwelche Fragen darüber, wenden Sie sich bitte an
@email{privacy@@mysql.com}.

Allgemeine Informationsanfragen schicken Sie bitte an @email{info@@mysql.com}.


@node Licensing and Support, MySQL 4.0 In A Nutshell, What is MySQL AB, Deutsch
@c German node Lizensierung and Support
@section MySQL Support and Lizensierung

@cindex Lizensierungsbedingungen
@cindex Supportbedingungen

Dieser Abschnitt beschreibt die MySQL Support und Lizensierungsvereinbarungen


@menu
* Support::                     
* Copyright::                   
* MySQL AB Logos and Trademarks::  
* Lizenzpolitik::               
@end menu

@node Support, Copyright, Licensing and Support, Licensing and Support
@c German node Support
@subsection Support den MySQL AB anbietet

@cindex Support, Arten
@cindex Arten von Support
@cindex Kommerzieller Support, Arten
@cindex Kosten, Support
@cindex Lizensierungskosten
@cindex Supportkosten
@cindex Preise, Support

Wir versuchen, technischen Support in einem breiten und umfassenden
Blickwinkel zu sehen. Fast jedes Problem im Zusammenhang mit
MySQL-Software ist für uns wichtig, wenn es für Sie wichtig ist.
Typischerweise suchen Kunden Hilfe dabei, wie man unterschiedliche
Befehle und Dienstprogramme zum Funktionieren bringt, wie
Performance-Flaschenhälse beseitigt werden können, wie man beschädigte
Systeme repariert, wie sich Betriebssysteme oder Netzwerkkonfigurationen
auf MySQL auswirken, wie man Datensicherung und Wiederherstellung
optimal konfiguriert, wie man APIs benutzt usw.
Unser Support deckt nur den MySQL-Server und unsere eigenen
Dienstprogramme ab, nicht Produkte Dritter, die auf den MySQL-Server
zugreifen, obwohl wir auch hierbei versuchen, zu helfen wo wir können.

Detaillierte Informationen über unsere unterschiedlichen
Support-Optionen finden Sie auf @uref{https://order.mysql.com/}, wo auch
Support-Verträge online bestellt werden können. Wenn Sie nur
beschränkten Zugriff auf das Internet haben, setzen Sie sich mit unserem
Vertrieb unter @email{sales@@mysql.com} in Verbindung.

Technischer Support ist wie eine Lebensversicherung. Sie können
jahrelang ohne solches glücklich sein, doch wenn die Stunde schlägt,
kann es zu spät sein, diese(n) zu kaufen!
Wenn Sie den MySQL-Server für wichtige Applikationen nutzen und
plötzlich Problemen begegnen, kann es möglicherweise zu lange dauern,
alle Antworten selbst herauszufinden. Es kann daher sein, dass Sie
unmittelbaren Zugriff auf die erfahrensten MySQL-Problemlöser benötigen,
und da

@node Copyright, MySQL AB Logos and Trademarks, Support, Licensing and Support
@c German node Copyright
@subsection Copyrights und Lizenzen, die von MySQL verwendet werden.

@cindex copyrights
@cindex licenses

@code{MySQL AB} besitzt das Copyright des MySQL Quellcodes,
der MySQL Logos and Schutzmarken und dieses Handbuch
@xref{What is MySQL AB}.
Es gibt einige verschiedene Lizenzen, die für die MySQL Distribution
relevant sind:

@enumerate
@item

Der MySQL-spezifische Quelltext, der benötigt wird, um die
@code{mysqlclient}-Bibliothek zu kompilieren, ist unter der @code{LGPL}
lizensiert. Programme im @file{client}-Verzeichnis sind GPL. Jede Datei hat
einen Header, aus dem ersichtlich ist, welches Copyright für diese Datei
gilt.

@item Die Client-Bibliothek und die (GNU @code{getopt})-Bibliothek werden
von der ``GNU LIBRARY GENERAL PUBLIC LICENSE'' abgedeckt.  @xref{LGPL license}.

@item
Der gesamte Quelltext des Servers und der (GNU @code{readline})-Bibliothek
werden von der ``GNU GENERAL PUBLIC LICENSE'' abgedeckt. @xref{GPL license}.
Diese findet sich unter anderem als Datei @file{COPYING} in den
Distributionen.

@item Einige Teile des Quelltextes (die @code{regexp}-Bibliothek) werden
von einem Copyright in Berkeley-Art abgedeckt.

@item
Ältere Versionen von (3.22 und früher) stehen unter einer
strikteren Lizenz
(@uref{http://www.mysql.com/support/arrangements/mypl.html}).
Bitte beachten sie die Dokumentation der speziellen Version für
weitere Informationen.


@item
Das Handbuch steht @emph{nicht} unter einer GPL-artigen Lizenz.
Die Benutzung des Handbuchs unterliegt den folgenden Bestimmungen.
@itemize @bullet
@item
Die Konvertierung in andere Formate ist erlaubt, der Inhalt jedoch
darf auf keinen Fall geändert oder bearbeitet werden.
@item
Sie können eine gedruckte Version für den Privaten Gebrauch erstellen
@item
Für alle anderen Zwecke, wie den Verkauf von gedruckten Kopien
oder die Verwendung (auch in Teilen) des Handbuchs in anderen
Veröffentlichungen, ist eine vorherige Vereinbarung mit MySQL AB 
erforderlich.
@end itemize
Bitte senden Sie eine E-Mail an @email{docs@@mysql.com} für weitere Informationen
oder wenn Sie daran interessiert sind, eine Übersetzung zu erstellen.
@end enumerate

Für Informationen darüber, wie die MySQL Lizenzen in der Praxis arbeiten
beachten Sie bitte @ref{Lizenzpolitik}.
Siehe auch @ref{MySQL AB Logos and Trademarks}.



@menu
* Verwendung des MySQL Servers unter einer kommerziellen Lizenz::  
* Webserver::                   
@end menu

@node Verwendung des MySQL Servers unter einer kommerziellen Lizenz, Webserver, Copyright, Copyright
@c German node <no English equivalent>
@subsubsection Verwendung des MySQL Servers unter einer kommerziellen Lizenz

@c German FIX added . after schreiben and after the xref.
@cindex ISP-Services
@cindex Services, ISP
@cindex Services, Web
@cindex Internet Service Provider

Internet Service Provider (ISP) hosten oft MySQL-Server für ihre Kunden.
Aufgrund der GPL-Lizenz ist hierfür keine Lizensierung erforderlich.

Auf der anderen Seite ermutigen wir Leute, ISPs zu benutzen, die
MySQL-Support haben, und das wird ihnen Vertrauen geben, dass ihr ISP im
Falle von Problemen mit ihrer MySQL-Installation helfen wird, das Problem
zu lösen (in manchen Fällen mit der Hilfe des MySQL-Entwicklungsteams).

Alle ISPs, die auf dem neuesten Stand der Dinge bleiben wollen, sollten sich
in die @code{announce}-Mailing-Liste eintragen, um auf der Hut zu sein vor
schwerwiegenden Problemen, die für ihre MySQL-Installationen relevant sein
könnten.

Beachten Sie bitte, dass ein ISP ohne MySQL-Lizenz seinen Kunden zumindest
Lesezugriff auf den Quelltext der MySQL-Installation geben sollte, damit
die Kunden feststellen können, dass diese korrekt gepatcht ist.


@node Webserver,  , Verwendung des MySQL Servers unter einer kommerziellen Lizenz, Copyright
@c German node <no English equivalent>
@subsubsection Einen Webserver betreiben, der MySQL benutzt

@cindex Webserver, betreiben
@cindex Einen Webserver betreiben

Wenn Sie MySQL in Verbindung mit einem Webserver unter Unix betreiben,
brauchen Sie nicht für eine Lizenz zu bezahlen.

Das gilt selbst dann, wenn Sie einen kommerziellen Webserver betreiben, der
MySQL benutzt, weil Sie nicht selbst eine eingebettete MySQL-Version
verkaufen. Dennoch bitten wir Sie, in einem solchen Fall MySQL-Support zu
kaufen, weil MySQL Ihrem Unternehmen hilft.


@node MySQL AB Logos and Trademarks, Lizenzpolitik, Copyright, Licensing and Support
@c German node MySQL AB Logos und Schutzmarken
@subsection MySQL-AB-Logos und -Schutzmarken

@cindex Logos
@cindex Schutzmarken

Viele MySQL-Datenbankbenutzer wollen auf Ihren Websites, ihren Büchern
und Packungsprodukten das MySQL-AB-Delphin-Logo zeigen. Wir begrüßen
das und ermuntern dazu, weisen aber darauf hin, dass das Wort
@code{MySQL} und das MySQL-Delphin-Logo Schutzmarken von MySQL AB sind
und nur so benutzt werden dürfen, wie in unserer Schutzmarken-Richtlinie
unter @uref{http://www.mysql.com/company/trademark.html} festgelegt.




@menu
* The Original MySQL logo::     
* MySQL Logos that may be Used Without Written Permission::  
* When need MySQL logo permission::  
* MySQL AB Partnership Logos::  
@end menu

@node The Original MySQL logo, MySQL Logos that may be Used Without Written Permission, MySQL AB Logos and Trademarks, MySQL AB Logos and Trademarks
@c German node Das Original-MySQL-Logo
@subsubsection Das Original-MySQL-Logo

@c FIX: picture: MySQL logo

Das MySQL-Delphin-Logo wurde von der finnischen Werbeagentur Priority im
Jahr 2001 entworfen. Der Delphin wurde als passendes Symbol für die
MySQL-Datenbank gewählt, weil er schlau, schnell und schlank ist und
mühelos durch die Daten-Ozeane navigiert. Ausserdem mögen wir Delphine.

Das Original-MySQL-Logo darf nur von Repräsentanten von MySQL AB und von
Personen benutzt werden, die eine schriftliche Erlaubnis hierfür haben.

@node MySQL Logos that may be Used Without Written Permission, When need MySQL logo permission, The Original MySQL logo, MySQL AB Logos and Trademarks
@c German node MySQL-Logos die ohne schriftliche Erlaubnis benutzt werden dürfen
@subsubsection MySQL-Logos die ohne schriftliche Erlaubnis benutzt werden dürfen

@c FIX: pictures: powered by, works with, included - logos

Wir haben einen Satz spezieller Logos für @emph{vorbehaltliche
Benutzung} angelegt, die von unserer Website unter
@uref{http://www.mysql.com/downloads/logos.html} herunter geladen werden
können und von Dritten auf ihren Websites ohne schriftliche Erlaubnis
von MySQL AB benutzt werden dürfen. Der Gebrauch dieser Logos ist - wie
der Name anzeigt - nicht völlig uneingeschränkt, sondern unterliegt
unseren Schutzmarken-Richtlinien, die Sie auf unserer Website finden.
Sie sollten diese Richtlinien lesen, wenn Sie planen, die Logos zu
benutzen. Die Anforderungen sind im Wesentlichen:

@itemize @bullet
@item
Benutzen Sie das gewünschte Logo von der @uref{http://www.mysql.com/}-
Site. Sie dürfen die Größe nach Ihren Bedürfnissen anpassen, aber keine
Farben oder das Design ändern noch die Grafik in sonstiger Form
verändern.

@item
Heben Sie hervor, dass Sie - und nicht MySQL AB - der Betreiber und
Eigner der Site ist, auf der die MySQL-Schutzmarke gezeigt wird.

@item
Sie dürfen die Schutzmarke nicht auf eine Weise benutzen, die MySQL AB
oder dem Wert der MySQL-AB-Schutzmarken schadet. Wir behalten uns das
Recht vor, das Recht zur Benutzung der MySQL-AB-Schutzmarke zu
widerrufen.

@item
Wenn Sie die Schutzmarke auf einer Website benutzen, machen Sie sie
anklickbar, wobei direkt nach @uref{http://www.mysql.com/} verlinkt
wird.

@item
Wenn Sie die MySQL-Datenbank unter GPL in einer Applikation benutzen,
muss Ihre Applikation (i) Open Source sein, (ii) in der Lage sein, sich
mit einem MySQL-Server zu verbinden.
@end itemize

Setzen Sie sich unter @email{trademark@@mysql.com} mit uns in
Verbindung, um wegen spezieller Arrangements anzufragen, die Ihren
Bedürfnissen entsprechen.

@node When need MySQL logo permission, MySQL AB Partnership Logos, MySQL Logos that may be Used Without Written Permission, MySQL AB Logos and Trademarks
@c German node Wann Sie eine Erlaubnis für die Benutzung des MySQL-Logos benötigen
@subsubsection Wann Sie eine Erlaubnis für die Benutzung des MySQL-Logos benötigen

In folgenden Fällen benötigen Sie eine schriftliche Erlaubnis von MySQL
AB, bevor Sie die MySQL-Logos benutzen:

@itemize @bullet
@item
Wenn Sie irgend ein MySQL-AB-Logo irgendwo ausser auf Ihrer Website
zeigen.

@item
Wenn Sie irgend ein MySQL-AB-Logo ausser den oben erwähnten Logos zur
@emph{vorbehaltlichen Benutzung} auf Websites oder anderswo anzeigen.
@end itemize

Aus rechtlichen und kommerziellen Gründen müssen wir die Benutzung der
MySQL-Schutzmarken auf Produkten, Büchern usw. beobachten. Üblicherweise
verlangen wir eine Gebühr für das Anzeigen von MySQL-AB-Logos auf
kommerziellen Produkten, weil wir der Meinung sind, das es vertretbar
ist, dass einige der Erlöse für die Weiterentwicklung der MySQL-
Datenbank zurückfließen.

@node MySQL AB Partnership Logos,  , When need MySQL logo permission, MySQL AB Logos and Trademarks
@c German node MySQL-AB-Partnerschafts-Logos
@subsubsection MySQL-AB-Partnerschafts-Logos

@c FIX: pictures: partnership logos - Bertrand?

@c German FIX part of the this paragraph was at the end of Lizenzpolitik.
@c (i.e. that section was pasted into the middle of this one ;-)
MySQL-Partnerschafts-Logos dürfen nur von Unternehmen und Personen
benutzt werden, die eine schriftliche Partnerschaftsvereinbarung mit
MySQL AB haben. Partnerschaften beinhalten eine Zertifizierung als
MySQL-Trainer oder -Berater. Sehen Sie bitte unter
@c German FIX change @xref into @ref 'cos it's not a separate sentence.
@ref{Business Services Partnering,,Partnerschaft} nach.

@node Lizenzpolitik,  , MySQL AB Logos and Trademarks, Licensing and Support
@c German node <no English equivalent>
@subsection MySQL-Lizenzpolitik

@cindex Lizenzpolitik
@cindex technischer Support, Lizensierung
@cindex Support, Lizensierung
@cindex General Public License, MySQL

Die formalen Bedingungen der GPL-Lizenz stehen unter @ref{GPL license}.
Im Wesentlichen ist unsere Lizenzpolitik und die Interpretation der
GPL wie folgt:

Beachten Sie bitte, dass ältere Versionen von MySQL immer noch einer 
@uref{http://www.mysql.com/Support/arrangements/mypl.html, strengeren
Lizenz} unterliegen. Sehen Sie in der Dokumentation der betreffenden
Version wegen entsprechender Informationen nach. Wenn Sie eine kommerzielle
Lizenz benötigen, weil die GPL-Lizenz nicht zu den Anforderungen Ihrer
Applikation passt, können Sie eine Lizenz unter
@uref{https://order.mysql.com/} kaufen.

Für normalen internen Gebrauch kostet MySQL nichts. Sie brauchen uns nichts
zu bezahlen, wenn Sie nicht wollen.

Eine Lizenz wird benötigt:

@itemize @minus
@item
Wenn Sie ein Programm, das nicht freie Software ist, mit Code des
MySQL-Servers oder der Client-Programme verbinden, die den GPL-Copyrights
unterliegen. Das ist zum Beispiel der Fall, wenn Sie MySQL als
eingebetteten Server (Embedded Server) in Ihren Applikationen benutzen,
oder wenn Sie dem MySQL-Server Erweiterungen hinzufügen, die nicht freie
Software sind. In diesen Fällen würden Ihre Applikation bzw. Ihr Code
ebenfalls GPL werden, weil die GPL in solchen Fällen wie ein Virus wirkt.
Sie können dieses Problem vermeiden, wenn Sie den MySQL-Server mit einer
kommerziellen Lizenz von MySQL AB erwerben.
Siehe @uref{http://www.gnu.org/copyleft/gpl-faq.html}.
@item
Wenn Sie eine kommerzielle Applikation haben, die NUR mit MySQL
funktioniert, und wenn Sie die Applikation zusammen mit dem MySQL-Server
ausliefern. Wir betrachten so etwas als Einbindung, selbst wenn es über das
Netzwerk geschieht.

@item
Wenn Sie eine Distribution von MySQL besitzen und nicht den Quelltext für
Ihre Kopie des MySQL-Servers zur Verfügung stellen, so wie es in der
GPL-Lizenz festgelegt ist.
xxx You have a Distribution of MySQL und you xxx Arjen: What does this mean: ...don't provide the
source code for your copy of the MySQL server ... xxx Shouldn't it be: for your application ... ??? xxx
, as defined in the GPL license. xxx
@end itemize

Eine Lizenz wird @strong{NICHT} benötigt:

@itemize @minus

@item
Sie benötigen keine Lizenz, wenn Sie den Client-Code in kommerzielle
Programme einschliessen. Der Client-Teil von MySQL unterliegt der
LGPL @code{GNU Library General Public License}-Lizenz. Der
@code{mysql}-Kommandozeilen-Client beinhaltet Code der
@code{readline}-Bibliothek, die unter @code{GPL} steht.

@item
Wenn Sie für Ihre Art der Benutzung von MySQL keine Lizenz benötigen, aber
MySQL mögen und die weitere Entwicklung fördern wollen, sind Sie herzlich
eingeladen, in jedem Fall eine Lizenz zu erwerben.

@item
Wenn Sie MySQL in einem kommerziellen Zusammenhang benutzen und davon
profitieren, bitten wir Sie, dass Sie die Weiterentwicklung von MySQL
fördern, indem Sie einen bestimmten Grad von Support kaufen. Wir meinen,
dass es vernünftig ist, wenn wir Sie bitten, MySQL zu unterstützen, wenn
MySQL Ihren Geschäften hilft. (Ansonsten würde es bei Support-Anfragen
bedeuten, dass Sie nicht nur etwas für umsonst benutzen, in das wir eine
Menge Arbeit gesteckt haben, sondern dass Sie uns auch noch auffordern,
kostenlosen Support zu liefern.)
@end itemize

In Situationen, wo eine MySQL-Lizenz benötigt wird, brauchen Sie eine
Lizenz pro Maschine, auf der der MySQL-Server läuft. Eine
Mehrprozessor-Maschine zählt jedoch als eine einzelne Maschine, und es gibt
keine Beschränkung hinsichtlich der Anzahl von MySQL-Servern, die auf einer
Maschine laufen, oder hinsichtlich der Anzahl von Clients, die zur gleichen
Zeit mit einem Server verbunden sind, der auf dieser Maschine läuft!

Falls Sie nicht sicher sind, ob für Ihre spezielle Benutzung von MySQL eine
Lizenz erforderlich ist, lesen Sie diesen Abschnitt bitte nochmals, bevor
Sie uns kontaktieren. @xref{Contact information}.

Wenn Sie eine MySQL-Lizenz benötigen, ist die Bezahlung am einfachsten,
wenn Sie das Lizenzformular auf dem Secure-Server von MySQL unter
@uref{https://order.mysql.com/} benutzen.
@c German FIX this section no longer exists (no price info in manual)
@c Andere Zahlungsformen werden unter @ref{Zahlungsinformationen} besprochen.


@menu
* Using MySQL word in presentations::  
* Using MySQL word in company and product names::  
@end menu

@node Using MySQL word in presentations, Using MySQL word in company and product names, Lizenzpolitik, Lizenzpolitik
@c German node Benutzung des Worts MySQL in Präsentationen
@subsubsection Benutzung des Worts @code{MySQL} in Druckmaterialien oder
Präsentationen

MySQL AB begrüßt Verweise auf die MySQL-Datenbank, aber das Wort
@code{MySQL} ist eine Schutzmarke von MySQL AB. Deshalb müssen Sie der
ersten oder deutlichsten Erwähnung des Worts @code{MySQL} das
Schutzmarken-Symbol @code{TM} hinzufügen, und wo angebracht deutlich
machen, dass @code{MySQL} eine Schutzmarke von MySQL AB ist. Details
entnehmen Sie bitte unserer Schutzmarken-Richtlinie unter
@uref{http://www.mysql.com/company/trademark.html}.


@node Using MySQL word in company and product names,  , Using MySQL word in presentations, Lizenzpolitik
@c German node Benutzung des Worts MySQL in Unternehmens- und Produktnamen
@subsubsection Benutzung des Worts @code{MySQL} in Unternehmens- und
Produktnamen

Die Benutzung des Worts @code{MySQL} in Produkt- und Unternehmensnamen
oder in Internet-Domänen-Namen ist nur mit vorheriger schriftlicher
Erlaubnis durch MySQL AB gestattet.


@node MySQL 4.0 In A Nutshell, MySQL Information Sources, Licensing and Support, Deutsch
@c German node MySQL 4.0 kurz und bündig
@section MySQL 4.0 kurz und bündig

Dateline: 16. Oktober 2001, Uppsala, Schweden

Lange durch MySQL AB angekündigt und lange von unseren Benutzern
erwartet: Der MySQL-Server 4.0 ist jetzt in der Alpha-Version zum
Herunterladen von @uref{http://www.mysql.com/} und unseren Mirrors
verfügbar.

Die neuen Haupt-Features des MySQL-Servers 4.0 sind eng mit unserem
bestehenden Geschäft und den Community-Nutzern verzahnt. Durch ihn wird
die MySQL-Datenbank-Software als Lösung für geschäftskritische
Schwerlast-Datenbanksysteme verbessert. Weitere neue Features zielen auf
die Benutzer eingebetteter Datenbanken.



@menu
* Nutshell Stepwise Rollout::   
* Nutshell Ready for Immediate Development Use::  
* Nutshell Embedded MySQL::     
* Nutshell Other features::     
* Nutshell Future features::    
* Nutshell 4.1 development release::  
@end menu

@node Nutshell Stepwise Rollout, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell, MySQL 4.0 In A Nutshell
@c German node Kurz und bündig - Schritt für Schritt
@subsection Schritt für Schritt

Das Erscheinen des MySQL-Servers 4.0 wird in mehreren Schritten
erfolgen, wobei die erste Version 4.0.0 genannt wird und bereits die
meisten neuen Features enthält. Zusätzliche Features werden in die
Versionen 4.0.1, 4.0.2 usw. eingebaut, höchstwahrscheinlich innerhalb
weniger Monate. MySQL 4.0 wird als Beta gekennzeichnet. In MySQL 4.1
werden dann weitere neue Features hinzugefügt. Es wird angestrebt, das
Alpha-Release Anfang 2002 herauszubringen.


@node Nutshell Ready for Immediate Development Use, Nutshell Embedded MySQL, Nutshell Stepwise Rollout, MySQL 4.0 In A Nutshell
@c German node Kurz und bündig - für den sofortigen Entwicklungseinsatz
@subsection Für den sofortigen Entwicklungseinsatz

Es wird nicht empfohlen, Produktionssysteme auf den MySQL-Server 4.0
umzustellen, bis dieser in der Beta-Version veröffentlicht wird. Selbst
das anfängliche Release hat unsere ausgiebigen Tests ohne jegliche
Fehler durchlaufen, auf allen Plattformen, auf denen wir testen. Wegen
der großen Zahl neuer Features empfehlen wir daher den MySQL-Server
selbst in der Alpha-Version für Entwicklungsarbeiten, wobei in Betracht
gezogen werden kann, dass der MySQL-Server 4.0 das Stadium "stabil"
erreichen wird, bevor Applikationen hiermit veröffentlicht werden, die
jetzt im Entwicklungsstadium sind.


@node Nutshell Embedded MySQL, Nutshell Other features, Nutshell Ready for Immediate Development Use, MySQL 4.0 In A Nutshell
@c German node Kurz und bündig - eingebettetes MySQL
@subsection Eingebettetes MySQL

@code{libmysqld} macht den MySQL-Server für einen erheblich ausgedehnten
Bereich von Applikationen geeignet. Wenn man die eingebettete MySQL-
Server-Bibliothek benutzt, kann man den MySQL-Server in
unterschiedlichste Applikationen und elektronische Geräte einbetten, bei
denen der Endbenutzer keinerlei Ahnung davon hat, dass ihnen eine
Datenbank unterlegt ist. Der eingebettete MySQL-Server ist ideal für
Benutzung hinter den Kulissen in Internet-Geräten, öffentlichen Kiosken,
schlüsselfertigen Hardware-/Software-Einheiten, Hochlast-Internet-
Servern oder Datenbanken, die auf CD-ROM vertrieben werden.

Viele Benutzer von eingebettetem MySQL können von der @emph{dualen
Lizensierung} der MySQL-Software profitieren. Neben der GPL-Lizenz sind
auch kommerzielle Lizenzen für diejenigen verfügbar, die nicht an die
GPL gebunden sein wollen. Die eingebettete MySQL-Bibliothek benutzt
dieselbe Schnittstelle wie die normale Client-Bibliothek und ist daher
angenehm und leicht zu benutzen. @xref{libmysqld}.


@node Nutshell Other features, Nutshell Future features, Nutshell Embedded MySQL, MySQL 4.0 In A Nutshell
@c German node Kurz und bündig - weitere Features
@subsection Weitere ab MySQL 4.0.0 verfügbare Features

@itemize @bullet
@item
Version 4.0 erhöht die @emph{Geschwindigkeit des MySQL-Servers} in
einigen Bereichen noch weiter, zum Beispiel bei Massen-@code{INSERT}s,
beim Suchen auf komprimierten Indexen, der Erzeugung von
@code{FULLTEXT}-Indexen oder auch bei @code{COUNT(DISTINCT)}.

@item
Der Tabellen-Handler @code{InnoDB} wird jetzt als Feature des
standardmäßigen MySQL-Servers angeboten und enthält vollständige
Unterstützung für @code{Transaktionen} und @code{Sperren auf
Zeilenebene}.

@item
Der MySQL-Server 4.0 unterstützt sichere Kommunikation zwischen Client
und Server, wodurch die Sicherheit gegen böswilliges Eindringen und
unbefugten Zugriff erheblich erhöht wird. Bei Web-Applikationen, die ein
Grundpfeiler der MySQL-Benutzung sind, konnten Web-Entwickler immer
schon SSL verwenden, um den Verkehr zwischen Endbenutzer-Browser und der
Web-Applikation zu sichern, sei sie nun in PHP, Perl, ASP oder mit
irgend einem anderen Web-Entwicklungswerkzeug geschrieben. Der Verkehr
zwischen dem Entwicklungswerkzeug und dem mysqld-Serverprozess konnte
bislang aber nur dadurch gesichert werden, dass die Prozesse auf
Computern innerhalb derselben Firewall residierten. Ab MySQL-Server 4.0
kann der @emph{mysqld}-Server-Daemon-Prozess selbst @code{Secure Sockets
Layer} (@code{SSL}) benutzen, was ihn in die Lage versetzt, eine sichere
Datenübertragung zwischen einer MySQL-Datenbank und beispielsweise einer
Windows-Applikation ausserhalb der Firewall aufzubauen.

@item
Unsere deutschen, österreichischen und schweizerischen Benutzer werden
bemerken, dass es einen neuen Zeichensatz latin_de gibt, der die
@emph{deutsche Sortierreihenfolge} beinhaltet, indem deutsche Umlaute in
derselben Sortierung erscheinen wie bei deutschen Telefonbüchern üblich.

@item
Zu den Features, die die @code{Migration} von anderen Datenbanksystemen
zum MySQL-Server erleichtern, gehören @code{TRUNCATE TABLE} (wie in
Oracle) und @code{IDENTITY} a1s Synonym für automatisch hochgezählte
Schlüssel (wie in Sybase). viele Benutzer werden sich auch darüber
freuen, dass der MySQL-Server jetzt das @code{UNION}-Statement
unterstützt, ein lang erwartetes Standard-SQL-Feature.

@item
Bei der Erstellung neuer Features für neue Benutzer haben wir die
Gemeinschaft treuer Benutzer nicht vergessen. Es gibt jetzt Multi-
Tabellen-@code{DELETE}-Statements. Durch das Hinzufügen von
Unterstützung für @code{symbolisches Verknüpfen} von @code{MyISAM} auf
Tabellenebene (und nicht nicht - wie bisher - auf Datenbankebene), sowie
durch das vorgabemäßige Anschalten der Verknüpfungen unter Windows
hoffen wir zeigen zu können, dass wir Verbesserungsvorschläge ernst
nehmen. Funktionen wie @code{SQL_CALC_FOUND_ROWS} und
@code{FOUND_ROWS()} ermöglichen herauszufinden, wie viele Zeilen eine
Anfrage ohne eine @code{LIMIT}-Klausel zurückgegeben hätte.
@end itemize


@node Nutshell Future features, Nutshell 4.1 development release, Nutshell Other features, MySQL 4.0 In A Nutshell
@c German node Kurz und bündig - zukünftige Features
@subsection Zukünftige Features in MySQL 4.0

Für die kommenden Releases des MySQL-Servers 4.0 (4.0.1, 4.0.2 usw.)
können Sie folgende Features erwarten, die noch in der Entwicklung sind:

@itemize @bullet
@item
Benutzer des MySQL-Servers für geschäftskritische Hochlast-Anwendungen
werden die Ergänzungen unseres Replikationssystems und unsere Online-
"Hot"-Datensicherung begrüßen. Spätere Versionen von 4.0 werden
@code{absturzsichere Replikation} beinhalten, die es bereits in Version
4.0.0 gibt, sowie den @code{LOAD DATA FROM MASTER}-Befehl, der bald das
Aufsetzen von Slaves automatisieren wird. @code{online backup} wird das
Hinzufügen eines neuen Replikations-Slaves erleichtern, ohne dass man
den Master herunterfahren muss, und es gibt auf Systemen mit vielen
Aktualisierungen nur geringe Geschwindigkeitseinbussen.

@item
Als Bequemlichkeits-Feature für Datenbank-Administratoren wird
hinzugefügt, dass mysqld-Parameter (Startoptionen) bald ohne das
Herunterfahren des Servers gesetzt werden können.

@item
Die neuen Eigenschaften des MySQL-Servers 4.0 für die Volltext-
(@code{FULLTEXT})-Suche ermöglichen die @code{FULLTEXT}-Indexierung
großer Texte sowohl mit binärer wie auch mit natürlichsprachiger
Suchlogik. Benutzer können minimale Wortlängen anpassen und ihre
eigenen Stopp-Wort-Listen in jeder menschlichen Sprache festlegen,
wodurch gänzlich neue Applikationen ermöglicht werden, die auf dem
MySQL-Server aufbauen.

@item
Viele Applikationen mit starkem Lesezugriff werden durch die noch weiter
erhöhte Geschwindigkeit des neu geschriebenen @code{Schlüssel-Caches}
profitieren.

@item
Viele Entwickler wird auch die @code{MySQL-Befehlshilfe} im Client
freuen.
@end itemize


@node Nutshell 4.1 development release,  , Nutshell Future features, MySQL 4.0 In A Nutshell
@c German node Kurz und bündig - Entwicklungs-Release
@subsection MySQL 4.1, das folgende Entwicklungs-Release

Intern wird durch das neue .frm-Dateiformat für Tabellendefinitionen in
MySQL-Server 4.0 die Grundlage für neue Features in MySQL-Server 4.1
gelegt, beispielsweise @code{verschachtelte Unterabfragen},
@code{gespeicherte Prozeduren} und @code{Fremdschlüssel-
Integritätsregeln}, die ganz oben auf der Wunschliste vieler unserer
Kunden stehen. Daneben werden auch einfachere Erweiterungen wie Multi-
Tabellen-@code{UPDATE}-Statements hinzugefügt.

Nach diesen Ergänzungen werden Kritiker des MySQL-Datenbankservers es
noch schwerer haben, auf Schwächen des MySQL-Datenbank-Managementsystems
hinzuweisen. MySQL, das seit langem für seine Stabilität,
Geschwindigkeit und Einfachheit der Benutzung bekannt ist, wird dann den
Anforderungen sehr anspruchsvoller Käufer genügen.


@node MySQL Information Sources, Compatibility, MySQL 4.0 In A Nutshell, Deutsch
@c German node MySQL-Informationsquellen
@section MySQL-Informationsquellen



@menu
* Portals::                     
* Questions::                   
@end menu

@node Portals, Questions, MySQL Information Sources, MySQL Information Sources
@c German node Portale
@subsection MySQL-Portale

@cindex MySQL-Portale
@cindex Handbücher, über MySQL
@cindex Bücher, über MySQL
@cindex MySQL-Testimonials
@cindex Benutzer, von MySQL
@cindex News-Sites
@cindex Suchmaschinen, Web
@cindex Web-Suchmaschinen
@cindex Online-Magazine
@cindex Magazine, online
@cindex Websites
@cindex Dienstleistungen
@cindex PHP, Websites
@cindex Berater, Liste
@cindex Web-Seiten, verschiedene
@cindex @code{Contrib}-Verzeichnis
@cindex URLs zu MySQL-Informationen
@cindex MySQL-bezogene Informations-URLs

Die MySQL-Portale (@uref{http://www.mysql.com/portal/}) auf unserer
Website bieten ein breites Spektrum MySQL-bezogener Informationen und
Links. Sie sind so aufgebaut, dass Sie leicht die Dinge finden, die Sie
interessieren.

Sie können sich als Benutzer registrieren. In diesem Fall können Sie
alle Dinge in den Portalen kommentieren und bewerten und auch selbst
Dinge beisteuern. Bei der Registrierung können Sie auch angeben, ob und
- wenn ja - welche Newsletter aus welchen Kategorien Sie beziehen
wollen.

Einige der momentanen MySQL-Portal-Kategorien:

@itemize @bullet
@item Bücher
Hier finden Sie alle möglichen MySQL- oder Computer-bezogenen Bücher, die
Sie kommentieren, bewerten oder kaufen können. Während dieses Handbuch
(insbesondere die Online-Version) immer noch der richtige Platz für
aktuellste technische Informationen ist, ist sein vorrangiges Ziel,
alles zu enthalten, was man über das MySQL-Datenbanksystem wissen kann.
Manchmal ist es nett, ein gebundenes Buch zu haben, dass man im Bett
oder auf Reisen lesen kann. Wenn Sie ein Buch über die angegebenen
Hyperlinks kaufen, tragen Sie zur Entwicklung der MySQL-Software bei.

@item Entwicklung
Dieses Portal hat Links auf Seiten, die den MySQL-Server für
unterschiedliche Zwecke benutzen, mit einer Beschreibung jeder Site.
Diese Informationen können Ihnen eine gute Vorstellung davon geben, wer
MySQL-Datenbank-Software benutzt und wie der MySQL-Server ihre
Anforderungen erfüllt.
Teile Sie uns auch @emph{Ihre} Site oder Erfolgsgeschichte mit!
 
@item Software 
Hier finden Sie eine Vielzahl von Applikationen und Wrappern, die den
MySQL-Server benutzen, die Sie auch herunter laden können.

@item Distributionen 
Hier finden Sie die verschiedenen Linux-Distributionen und weitere
Software-Pakete, die die MySQL-Software enthalten.

@item Berater 
Hier finden Sie Informationen über MySQL-Berater.

@item Partner 
Hier finden Sie alle MySQL-Partner.
@end itemize


@node Questions,  , Portals, MySQL Information Sources
@c German node Fragen
@subsection MySQL-Mailing-Listen

@cindex Berichten, Fehler
@cindex MySQL-Mailing-Listen


Dieser Abschnitt führt Sie in die MySQL-Mailing-Listen ein und zeigt einige
Richtlinien und ihre Benutzung auf.


@menu
* Mailing-list::                
* Asking questions::            
* Bug reports::                 
* Answering questions::         
@end menu

@node Mailing-list, Asking questions, Questions, Questions
@c German node Mailing-Listen
@subsubsection Die MySQL-Mailing-Listen

@cindex Mailing-Listen
@cindex E-Mail-Listen

Um die MySQL-Haupt-Mailing-Liste zu abonnieren, schicken Sie eine Nachricht
an die E-Mail-Adresse @email{mysql-subscribe@@lists.mysql.com}.

Um sich aus der MySQL-Haupt-Mailing-Liste auszutragen, schicken Sie eine
Nachricht an die E-Mail-Adresse @email{mysql-unsubscribe@@lists.mysql.com}.

Von Bedeutung ist nur die Adresse, unter der Sie Ihre Nachrichten
abschicken. Betreffzeile und Text der Nachricht werden ignoriert.

@c the last two addresses in this paragraph are NOT @email because they
@c shouldn't be live links.
Wenn Ihre Antwortadresse nicht gültig ist, können Sie Ihre Adresse explizit
angeben. Fügen Sie einen Bindestrich zum Abonnement- oder
Abmelde-Kommando hinzu, gefolgt von Ihrer Adresse, wobei das
@samp{@@}-Zeichen in Ihrer Adresse durch @samp{=} ersetzt wird. Um sich zum
Beispiel mit @code{your_name@@host.domain} einzutragen, schicken Sie eine
Nachricht an @code{mysql-subscribe-your_name=host.domain@@lists.mysql.com}.

Mails an @email{mysql-subscribe@@lists.mysql.com} oder
@email{mysql-unsubscribe@@lists.mysql.com} werden automatisch vom ezmlm
Mailing-Listen-Prozessor bearbeitet. Informationen über ezmlm sind
auf @uref{http://www.ezmlm.org, The ezmlm Website} verfügbar.

Um eine Nachricht an die Liste selbst zu schicken, schicken Sie eine Mail
an @code{mysql@@lists.mysql.com}. Schicken aber bitte @emph{keine} Mail an
@email{mysql@@lists.mysql.com}, die das Abonnieren oder Austragen betrifft,
denn Mails an diese Adresse werden automatisch an tausende anderer Benutzer
verteilt.

@c __review__jan_2001_11_13 
Wenn Ihre lokale Site viele Abonnenten für @email{mysql@@lists.mysql.com}
hat, sollten Sie evtl. eine lokale Mailing-Liste einrichten, so dass
Nachrichten, die von @code{lists.mysql.com} an Ihre Site gesandt werden, an
die lokale Liste verteilt werden. In solchen Fällen wenden Sie sich bitte
an Ihre Systemadministrator, um zur lokalen Mailing-Liste hinzugefügt oder
aus ihr gelöscht zu werden.

Wenn Sie wollen, dass der Traffic einer Mailing-Liste in eine separate
Mailbox Ihres E-Mail-Programms geleitet wird, setzen Sie einen Filter,
der auf die E-Mail-Header (Kopfdaten) reagiert. Sie können dazu entweder
den @code{List-ID:}- oder den @code{Delivered-To:}-Header benutzen, um die
Listennachrichten zu erkennen.

Die folgenden MySQL-Mailing-Listen existieren:

@table @code
@item @email{announce-subscribe@@lists.mysql.com} announce
Diese Liste kündigt neue Versionen von MySQL und verwandter Programme an.
Sie hat geringen Traffic; alle MySQL-Benutzer sollten sie abonnieren.

@item @email{mysql-subscribe@@lists.mysql.com} mysql
Die Hauptliste für allgemeine MySQL-Diskussionen. Bitte beachten Sie, dass
bestimmte Themen besser in spezialisierteren Listen diskutiert werden. Wenn
Sie an die falsche Liste posten, erhalten Sie vielleicht keine Antwort!

@item @email{mysql-digest-subscribe@@lists.mysql.com} mysql-digest
Die @code{mysql}-Liste in Digest-Form (zusammengefasst). Anstelle
individueller Nachrichten wird einmal pro Tag eine große Mail mit allen
Nachrichten dieses Tages geschickt.

@item @email{bugs-subscribe@@lists.mysql.com} bugs
An diese Liste sollte Sie ausschließlich komplette, wiederholbare
Bug-Berichte schicken, indem Sie das @code{mysqlbug}-Skript benutzen. (Wenn
Sie unter Windows arbeiten, sollten Sie eine Beschreibung des
Betriebssystems und der MySQL-Version hinzufügen.)
Vorzugsweise sollten Sie den Problemfall mit der letzten stabilen oder
Entwicklungs-Version von MySQL testen, bevor Sie den Bericht posten! Jeder
sollte in der Lage sein, den Bug zu wiederholen, indem einfach @code{mysql
test < Skript} auf den beigefügten Testfall angewandt wird. Alle Bugs, die
auf dieser Liste gepostet werden, werden im nächsten MySQL-Release behoben
oder dokumentiert! Wenn nur kleinere Code-Änderungen betroffen sind, werden
wir zusätzlich ein Patch bereitstellen, das das Problem behebt.

@item @email{bugs-digest-subscribe@@lists.mysql.com} bugs-digest
Die Digest-Version (zusammengefasst) der @code{bugs}-Liste.

@item @email{internals-subscribe@@lists.mysql.com} internals
Eine Liste für Leute, die am MySQL-Code arbeiten. Auf dieser Liste kann man
auch die MySQL-Entwicklung diskutieren und Patches posten.

@item @email{internals-digest-subscribe@@lists.mysql.com} internals-digest
Die Digest-Version (zusammengefasst) der @code{internals}-Liste.

@item @email{java-subscribe@@lists.mysql.com} java
Diskussionen über MySQL und Java, hauptsächlich über JDBC-Treiber.

@item @email{java-digest-subscribe@@lists.mysql.com} java-digest
Eine @code{java}-Liste.

@item @email{win32-subscribe@@lists.mysql.com} win32
Alles betreffend MySQL auf Microsoft-Betriebssystemen wie Win95, Win98, NT, XP,
und Win2000.

@item @email{win32-digest-subscribe@@lists.mysql.com} win32-digest
Die Digest-Version (zusammengefasst) der @code{win32}-Liste.

@item @email{myodbc-subscribe@@lists.mysql.com} myodbc
Alles betreffend ODBC-Verbindungen zu MySQL.

@item @email{myodbc-digest-subscribe@@lists.mysql.com} myodbc-digest
Die Digest-Version (zusammengefasst) der @code{myodbc}-Liste.

@item @email{plusplus-subscribe@@lists.mysql.com} plusplus
Alles, was das Programmieren mit der C++-API von MySQL betrifft.

@item @email{plusplus-digest-subscribe@@lists.mysql.com} plusplus-digest
Die Digest-Version (zusammengefasst) der @code{plusplus}-Liste.

@c __review_jan_2001_11_13
@item @email{msql-mysql-modules-subscribe@@lists.mysql.com} msql-mysql-modules
Eine Liste zur Perl-Unterstützung in MySQL. msql-mysql-modules

@item @email{msql-mysql-modules-digest-subscribe@@lists.mysql.com} msql-mysql-modules-digest
Die Digest-Version (zusammengefasst) der @code{msql-mysql-modules}-Liste.
@end table

Alle Listen abonnieren Sie - und tragen sich wieder aus - auf dieselbe Art
wie oben beschrieben. Tragen Sie in Ihre Mail zum Abonnieren oder Austragen
die entsprechende Mailing-Liste ein anstelle von @code{mysql}. Um sich zum
Beispiel für die @code{myodbc}-Liste einzutragen, schicken Sie eine
Nachricht an @email{myodbc-subscribe@@lists.mysql.com} oder
@email{myodbc-unsubscribe@@lists.mysql.com}.

Wenn Sie keine Antwort auf Ihre Fragen von der Mailing-Liste erhalten, ist
eine Option, für den Support von MySQL AB zu bezahlen, was Sie in direkten
Kontakt mit den MySQL-Entwicklern bringt. @xref{Support}.

Die folgende Tabelle listet einige Mailing-Listen in anderen Sprachen als
englisch auf. Beachten Sie, dass diese nicht von MySQL AB unterhalten
werden. Daher können wir nicht für die Qualität dieser Listen garantieren.

@table @code
@item @email{mysql-france-subscribe@@yahoogroups.com} Eine französische Mailing-Liste
@item @email{list@@tinc.net} Eine koreanische Mailing-Liste
Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql
your@@email.address} an diese Liste.
@item @email{mysql-de-request@@lists.4t2.com} Eine deutsche Mailing-Liste
Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql-de
your@@email.address} an diese Liste.
Informationen über diese Liste finden Sie unter
@uref{http://www.4t2.com/mysql}.
@item @email{mysql-br-request@@listas.linkway.com.br} Eine portugiesische Mailing-Liste.
Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql-br
your@@email.address} an diese Liste.
@item @email{mysql-alta@@elistas.net} Eine spanische Mailing-Liste.
Schicken Sie eine E-Mail mit dem Betreff @code{subscribe mysql
your@@email.address} an diese Liste.
@end table


@node Asking questions, Bug reports, Mailing-list, Questions
@c German node Fragen stellen
@subsubsection Wie man Fragen stellt oder Bugs berichtet

@cindex Netz-Etikette
@cindex Mailing-Listen, Speicherort der Archive
@cindex Durchsuchen, MySQL-Webseiten

Bevor Sie einen Bug berichten oder eine Frage stellen, tun Sie bitte
folgendes:

@itemize @bullet
@item
Suchen Sie im MySQL-Online-Handbuch:
@*
@uref{http://www.mysql.com/documentation/manual.php}
@*
Wir bemühen uns, das Handbuch aktuell zu halten, indem wir es häufig mit
Lösungen für neu bekannt gewordene Probleme aktualisieren!

@item
Durchsuchen Sie die MySQL-Mailing-Listen-Archive:
@*
@uref{http://www.mysql.com/documentation/}
@*
@item
Sie können ausserdem @uref{http://www.mysql.com/search.html} benutzen, um
alle Webseiten zu durchsuchen (inklusive des Handbuchs), die unter
@uref{http://www.mysql.com/} zu finden sind.
@end itemize

Wenn Sie weder im Handbuch noch in den Archiven eine Antwort finden können,
versuchen Sie es mit Ihrem lokalen MySQL-Experten. Wenn Sie immer noch
keine Antwort auf Ihre Frage finden, lesen Sie den nächsten Abschnitt über
die Mailing-Listen unter @email{mysql@@lists.mysql.com}.


@node Bug reports, Answering questions, Asking questions, Questions
@c German node Bug-Berichte
@subsubsection Wie man Bugs oder Probleme berichtet

@cindex Bugs, berichten
@cindex Berichten, Bugs
@cindex Probleme, berichten
@cindex Fehler, berichten
@cindex @code{mysqlbug}-Skript
@cindex Erzeugen, Bug-Berichte
@cindex Skripts, @code{mysqlbug}

Einen guten Bug-Bericht zu schreiben braucht Geduld, aber es gleich beim
ersten Mal richtig zu machen spart Ihnen und uns Zeit. Ein guter
Bug-Bericht enthält einen kompletten Testfall für den Bug, der es sehr
wahrscheinlich macht, dass wir ihn im nächsten Release beheben. Dieser
Abschnitt hilft Ihnen, Ihren Bericht korrekt zu schreiben, damit Sie Ihre
Zeit nicht damit verschwenden, etwas zu schreiben, was uns wenig oder gar
nicht weiterhilft.

Wir ermutigen jeden, das @code{mysqlbug}-Skript zu benutzen, um einen
Bug-Bericht anzufertigen (oder einen Bericht über irgendein anderes
Problem), falls das möglich ist. Der @code{mysqlbug} findet sich im
@file{Skripts}-Verzeichnis der Quelldistribution, bzw. im
@file{bin}-Verzeichnis der Binärdistribution, im Verzeichnis unterhalb
Ihres MySQL-Installationsverzeichnisses. Falls es Ihnen nicht möglich ist,
@code{mysqlbug} zu benutzen, sollten Sie trotzdem alle notwendigen
Informationen mitliefern, die in diesem Abschnitt aufgeführt sind.

Das @code{mysqlbug}-Skript hilft Ihnen, einen Bericht zu erstellen, der
viele der folgenden Informationen automatisch einschließt, aber falls
etwas Wichtiges fehlt, fügen Sie es bitte Ihrer Nachricht hinzu! Bitte
lesen Sie diesen Abschnitt sorgfältig und stellen Sie sicher, dass alle
hier beschriebenen Informationen in Ihrem Bericht enthalten sind.

@cindex Bug-Berichte, E-Mail-Adresse
Für gewöhnlich sollten Sie Ihren Bug-Bericht und Probleme an
@email{mysql@@lists.mysql.com} schicken. Wenn Sie einen Testfall erzeugen
können, der den Bug klar demonstriert, sollten Sie ihn an die
@email{bugs@@lists.mysql.com}-Liste schicken. Beachten Sie, dass Sie nur
einen kompletten, nachvollziehbaren Bug-Bericht an diese Liste schicken
sollten, indem Sie das @code{mysqlbug}-Skript benutzen. Falls Sie unter
Windows arbeiten, sollten Sie eine Beschreibung des Betriebssystems und der
MySQL-Version hinzufügen. Vorzugsweise sollten Sie den Problemfall mit der
letzten stabilen oder Entwicklungs-Version von MySQL testen, bevor Sie den
Bericht posten! Jeder sollte in der Lage sein, den Bug zu wiederholen,
indem einfach @code{mysqltest < Skript} auf den beigefügten Testfall
angewandt wird. Alle Bugs, die auf dieser Liste gepostet werden, werden im
nächsten MySQL-Release behoben oder dokumentiert! Wenn nur kleinere
Code-Änderungen betroffen sind, werden wir zusätzlich ein Patch
bereitstellen, das das Problem behebt.

Denken Sie daran, dass es immer möglich ist, auf eine Nachricht zu
antworten, die zu viele Informationen enthält, aber nicht immer auf eine,
die zu wenige Informationen enthält. Oft lassen Leute Fakten aus, weil sie
denken, die Ursache eines Probleme zu kennen und annehmen, dass einige
Details nicht von Wichtigkeit sind. Ein gutes Prinzip ist folgendes: Falls
Sie im Zweifel sind, ob Sie etwas Bestimmtes mitteilen sollten, teilen Sie
es mit! Es ist tausendmal schneller und weniger ärgerlich, ein paar Zeilen
mehr in Ihrem Bericht zu schreiben, als gezwungen zu sein, noch einmal zu
fragen und auf die Antwort zu warten, weil Sie beim ersten Mal nicht genug
Informationen geliefert haben.

Die häufigste Fehler besteht darin, dass Leute die Versionsnummer der
MySQL-Distribution, die sie benutzen nicht angeben, oder vergessen anzugeben, 
auf welcher Plattform sie MySQL installiert haben (inklusive der
Betriebssystem-Version). Diese Informationen sind äußerst relevant, und in
99 von 100 Fällen ist der Bug-Bericht ohne sie nutzlos! Sehr oft erhalten
wir Fragen wie 'Warum funktioniert das bei mir nicht?', nur um
herauszufinden, dass das beschriebene Feature nicht in der benutzten
MySQL-Version implementiert war, oder dass der Bug, der im Bericht
beschrieben wurde, bereits in einer neueren MySQL-Version behoben wurde.
Manchmal ist der Fehler plattformabhängig; in solchen Fällen ist es
praktisch unmöglich, irgend etwas zu beheben, ohne das Betriebssystem und
die Versionsnummer des Betriebssystems zu kennen.

Denken Sie auch daran, Informationen über Ihren Compiler einzuschließen,
falls sie MySQL selbst kompilieren. Oft finden Leute Fehler in
Compilern und denken, dass das Problem MySQL-bezogen ist. Die meisten
Compiler werden permanent weiter entwickelt und werden von Version zu
Version besser. Um festzustellen, ob ein Problem von Ihrem Compiler abhängt
oder nicht, müssen wir wissen, welcher Compiler benutzt wird. Beachten Sie,
dass jedes Compiler-Problem als Bug-Bericht betrachtet und deshalb
entsprechend berichtet werden sollte.

Es ist äußerst hilfreich, wenn eine gute Beschreibung des Probleme in
Ihrem Bug-Bericht eingeschlossen ist, das heißt ein gutes Beispiel aller
Dinge, die Sie getan haben, die zu dem Problem führten, sowie das Problem
selbst. Die besten Bug-Berichte sind diejenigen, die ein komplettes
Beispiel zeigen, wie man den Bug oder das Problem reproduzieren kann.
@xref{Reproduceable test case}.

Wenn ein Programm eine Fehlermeldung produziert, ist es sehr wichtig,
diese in Ihren Bericht einzuschließen! Wenn wir in den Archiven der
Programme suchen, ist es besser, wenn die Fehlernachricht exakt mit
derjenigen übereinstimmt, die das Programm produziert. (Sogar
Groß-/Kleinschreibung sollte berücksichtigt werden!) Sie sollten nie
versuchen, sich daran zu erinnern, was die Fehlernachricht war; stattdessen
sollten Sie die gesamte Nachricht per Kopieren und Einfügen in Ihrem
Bericht unterbringen!

Wenn Sie ein Problem mit MyODBC haben, sollten Sie versuchen, eine
MyODBC-Trace-Datei zu erstellen. @xref{MyODBC bug report}.

Bitten denken Sie daran, dass viele Leute, die Ihren Bericht lesen, dabei
ein 80-Spalten-Anzeigegerät benutzen. Wenn Sie Berichte oder Beispiele
erzeugen, indem Sie das @code{mysql}-Kommandozeilen-Werkzeug benutzen, sollten
Sie deshalb die @code{--vertical}-Option (oder den
@code{\G}-Statement-Begrenzer) für Ausgaben benutzen, die ansonsten die
verfügbare Anzeigebreite überschreiten würden (zum Beispiel beim
@code{EXPLAIN SELECT}-Statement; siehe dazu das Beispiel weiter unten).
@cindex Bug-Berichte, Kriterien für
Bitte schließen Sie folgende Informationen in Ihren Bug-Bericht ein:

@itemize @bullet
@item
Die Versionsnummer der MySQL-Distribution, die Sie benutzen (zum Beispiel
MySQL Version 3.23.22). Sie finden heraus, welche Version Sie benutzen,
indem Sie @code{mysqladmin version} eingeben. @code{mysqladmin} findet
sich im @file{bin}-Verzeichnis unterhalb Ihres
MySQL-Installationsverzeichnisses.

@item
Hersteller und Modell der Maschine, auf der Sie arbeiten.

@item
Name und Version des Betriebssystems. Bei den meisten Betriebssystemen
läßt sich diese Information herausfinden, indem man das Unix-Kommando
@code{uname -a} ausführt.

@item
Manchmal ist die Größe des Arbeitsspeichers (real und virtuell) relevant.
Im Zweifelsfall schließen Sie diese Werte ein.

@item
Wenn Sie eine Quelldistribution von MySQL benutzen, werden Name und
Versionsnummer des Compilers benötigt. Wenn Sie eine Binärdistribution
haben, geben Sie den Namen der Distribution an.

@item
Wenn das Problem während der Kompilation auftritt, schließen Sie die
exakte Fehlermeldung (bzw. -meldungen) ein und zusätzlich ein paar Zeilen
des Kontextes um den problembehafteten Code herum in der Datei, wo der
Fehler auftrat.

@item
Falls @code{mysqld} abstürzt, sollten Sie auch die Anfrage (Query)
mitteilen, die @code{mysqld} zum Absturz brachte. Gewöhnlich können Sie das
herausfinden, indem Sie @code{mysqld} mit angeschaltetem Logging laufen
lassen. @xref{Using log files}.

@item
Falls irgend eine Datenbanktabelle mit dem Problem zu tun hat, schließen
Sie die Ausgabe von @code{mysqldump --no-data db_name tbl_name1 tbl_name2
...} ein. Das ist sehr leicht zu bewerkstelligen und eine sehr hilfreiche
Möglichkeit, Informationen über jegliche Tabelle in einer Datenbank zu
erhalten, die uns hilft, eine Situation herzustellen, die mit derjenigen
übereinstimmt, die Sie haben.

@item
Bei Bugs, die sich auf Geschwindigkeitsprobleme beziehen, oder bei
Problemen mit @code{SELECT}-Statements, sollten Sie immer die Ausgabe von
@code{EXPLAIN SELECT ...} einschließen, und zumindest die Anzahl der
Zeilen, die das @code{SELECT}-Statement produziert. Je mehr Informationen
Sie uns über Ihre Situation geben, desto wahrscheinlicher ist es, dass
Ihnen jemand helfen kann! Das folgende Beispiel ist ein sehr gutes Beispiel
eines Bug-Berichts (es sollte natürlich mit dem @code{mysqlbug}-Skript
berichtet werden):

Beispiel unter Benutzung des @code{mysql}-Kommandozeilen-Werkzeugs (achten Sie
auf die Benutzung des @code{\G}-Statement-Begrenzers für Statements, deren
Ausgabebreite ansonsten die von 80-Zeilen-Ausgabegeräten überschreiten
würde):

@example
mysql> SHOW VARIABLES;
mysql> SHOW COLUMNS FROM ...\G
       <Ausgabe von SHOW COLUMNS>
mysql> EXPLAIN SELECT ...\G
       <Ausgabe von EXPLAIN>
mysql> FLUSH STATUS;
mysql> SELECT ...;
       <Eine Kurzfassung der Ausgabe von SELECT,
       inclusive der Zeit, die die Anfrage benötigte>
mysql> SHOW STATUS;
       <Ausgabe von SHOW STATUS>
@end example

@item
Wenn ein Problem auftritt, während @strong{mysqld} läuft, legen Sie nach
Möglichkeit ein Eingabeskript bei, das die Anomalie reproduziert. Dieses
Skript sollte alle notwendigen Quelltextdateien beinhalten. Je exakter das
Skript Ihre Situation reproduzieren kann, desto besser. Wenn Sie einen
wiederholbaren Testfall erstellen können, sollten Sie ihn an
@email{bugs@@lists.mysql.com} schicken, damit er mit hoher Priorität
behandelt wird!

Falls Sie kein Skript zur Verfügung stellen können, sollten Sie zumindest
die Ausgaben von @code{mysqladmin variables extended-status processlist} in
Ihrer Mail mitschicken, um einige Informationen darüber zu geben, wie Ihr
System arbeitet!

@item
Falls Sie keinen Testfall mit ein paar Zeilen produzieren können oder falls
Ihre Tabelle zu Groß ist, um an die Mailing-Liste geschickt zu werden
(mehr als 10 Zeilen), sollten Sie mit @code{mysqldump} einen Dump Ihrer
Tabellen machen und eine @file{README}-Datei erzeugen, die Ihr Problem
beschreibt.

Erzeugen Sie ein komprimiertes Archiv Ihrer Dateien, indem Sie @code{tar}
und @code{gzip} oder @code{zip} benutzen, und benutzen Sie @code{ftp}, um
das Archiv nach @uref{ftp://Support.mysql.com/pub/mysql/secret/} zu
transferieren. Schicken Sie danach eine kurze Beschreibung des Probleme an
@email{bugs@@lists.mysql.com}.

@item
Wenn Sie glauben, dass MySQL auf eine Anfrage hin merkwürdige Ergebnisse
liefert, fügen Sie nicht nur das Ergebnis bei, sondern auch, wie das
Ergebnis Ihrer Meinung nach aussehen sollte, sowie eine Erklärung, wie Sie
zu dieser Meinung gelangt sind.

@item
Wenn Sie ein Beispiel Ihres Problems schildern, ist es besser, die
Variablen-, Tabellen- etc. Namen zu verwenden, die in Ihrer aktuellen
Situation existieren, anstatt sich neue Namen auszudenken. Das Problem
könnte nämlich etwas mit dem Namen der Variablen oder Tabelle zu tun haben!
Diese Fälle sind zwar selten, aber hier sollte man lieber auf Nummer sicher
gehen. Letztlich sollte es für Sie auch leichter sein, ein Beispiel zur
Verfügung zu stellen, das Ihre tatsächliche Situation schildert, und es ist
in jedem Fall besser für uns. Falls Sie mit Daten arbeiten, die Sie keinen
anderen zeigen wollen, können Sie @code{ftp} benutzen, um die Daten nach
@uref{ftp://Support.mysql.com/pub/mysql/secret/} zu transferieren. Falls
die Daten streng geheim sind und Sie sie nicht einmal uns zeigen wollen,
legen Sie bitte ein Beispiel mit anderen Namen an, betrachten Sie dies aber
bitte als allerletzte Möglichkeit.

@item
Fügen Sie alle Optionen ein, die den relevanten Programmen übergeben
wurden, falls möglich. Geben Sie zum Beispiel die Optionen an, die Sie
benutzt haben, als Sie den @code{mysqld}-Daemon gestartet haben, und die
Sie für Client-Programme wie @code{mysql} benutzen, sowie
diejenigen, die Sie für die Konfiguration des @code{configure}-Skripts
nehmen, denn diesen sind oft der Schlüssel für Antworten und deshalb
äußerst relevant!
Es ist immer eine gute Idee, sie in jedem Fall anzugeben! Wenn Sie Module
wie Perl oder PHP benutzen, fügen Sie bitte die Versionszahl von diesen mit
ein.

@item
Wenn sich Ihre Frage auf das Berechtigungssystem (Zugriffsberechtigungen auf
den Datenbank-Server) bezieht, fügen Sie bitte die Ausgabe von
@code{mysqlaccess}, die Ausgabe von @code{mysqladmin reload} und alle
Fehlermeldungen, die Sie erhalten, wenn Sie versuchen, sich zu verbinden,
bei! Wenn Sie Ihre Zugriffsberechtigungen testen, sollten Sie zunächst
@code{mysqlaccess} ausführen. Führen Sie danach @code{mysqladmin reload
version} aus und versuchen Sie dann, sich mit dem Programm zu verbinden,
das Probleme macht. @code{mysqlaccess} liegt im @file{bin}-Verzeichnis
unter Ihrem MySQL-Installationsverzeichnis.
MySQL-Installationsverzeichnis.

@item
Wenn Sie einen Patch für ein Bug haben, ist das gut, aber nehmen Sie bitte
nicht an, dass der Patch alles ist, was wir brauchen. Gehen Sie auch nicht
davon aus, dass wir den Patch benutzen werden, wenn Sie nicht auch einige
notwendige Informationen mitschicken, zum Beispiel Testfälle, die den Bug
zeigen, der durch Ihren Patch behoben wird. Möglicherweise finden wir
Probleme, die Ihr Patch verursacht, oder wir verstehen ihn überhaupt nicht.
Wenn das der Fall ist, können wir ihn nicht benutzen.

Wenn wir nicht genau feststellen können, wofür der Patch gedacht ist,
werden wir ihn nicht benutzen. In diesen Fällen werden uns Testfälle weiter
helfen. Zeigen Sie darin auf, dass der Patch all die Situationen bewältigt,
die eintreten können. Falls wir einen Grenzfall finden (sogar, wenn es ein
seltener ist), bei dem der Patch nicht funktioniert, ist er vielleicht
nutzlos.

@item
Vermutungen, worin der Bug besteht, warum er auftritt oder wovon er
abhängt, sind meist falsch. Selbst das MySQL-Team kann solche Dinge nicht
erraten, sondern muss einen Debugger benutzen, um den wahren Grund des Bugs
feststellen zu können.

@item
Geben Sie in Ihrer Mail zu erkennen, dass Sie das Referenzhandbuch gelesen
und die Mail-Archive durchgesehen haben, damit andere wissen, dass Sie
versucht haben, das Problem selbst zu lösen.

@item
Wenn Sie einen @code{parse error} erhalten, überprüfen Sie bitte genau Ihre
Syntax! Wenn Sie nichts Falsches darin finden können, ist es sehr
wahrscheinlich, dass Ihre aktuelle Version von MySQL die Anfrage, die Sie
formuliert haben, nicht unterstützt. Wenn Sie die aktuelle Version benutzen
und das Handbuch unter @uref{http://www.mysql.com/documentation/manual.php}
die Syntax, die Sie benutzen, nicht beschreibt, unterstützt MySQL Ihre
Anfrage nicht. In diesem Fall bleibt Ihnen nur, die Syntax entweder selbst
zu implementieren oder per E-Mail an @email{mysql-licensing@@mysql.com}
nach einem Angebot für die Implementation anzufragen!

Wenn das Handbuch die Syntax, die Sie benutzen, beschreibt, Sie aber eine
ältere Version von MySQL benutzen, sollten Sie in der
MySQL-Änderungsgeschichte (Change History) nachsehen, wann die Syntax
implementiert wurde. In diesem Fall haben Sie die Möglichkeit, ein Upgrade
auf eine neuere Version von MySQL vorzunehmen.
@xref{News}.

@item
Wenn Sie ein Problem in der Art haben, dass Ihre Daten anscheinend
beschädigt sind oder Sie Fehlermeldungen bekommen, wenn Sie auf eine
bestimmte Tabelle zugreifen, sollten Sie zunächst Ihre Tabellen überprüfen
und anschließend reparieren, indem Sie @code{myisamchk} oder @code{CHECK
TABLE} und @code{REPAIR TABLE} benutzen.
@xref{MySQL Database Administration}.

@item
Wenn Sie oft beschädigte Tabellen erhalten, sollten Sie versuchen
herauszufinden, wann und warum das geschieht! In diesem Fall kann die
@file{mysql-data-directory/'hostname'.err}-Datei einige Informationen
darüber enthalten, was geschehen ist. @xref{Error log}. Bitte fügen Sie
jede relevante Information aus dieser Datei in Ihren Bug-Bericht ein!
Normalerweise sollte @code{mysqld} @strong{NIE} eine Tabelle zerstören,
ausser wenn der Server mitten während eines Updates gekillt wurde! Wenn Sie
den Grund für den Absturz von @code{mysqld} herausfinden können, ist es
sehr viel einfacher für uns, Ihnen eine Lösung des Problems an die Hand zu
geben!
@xref{What is crashing}.

@item
Falls möglich, sollten Sie die aktuellste Version von MySQL herunter laden,
installieren und überprüfen, ob das Ihr Problem löst. Alle Versionen
von MySQL werden gründlich getestet und sollten ohne Probleme
funktionieren! Wir halten uns daran, alles so abwärtskompatibel wie
möglich zu machen. Daher sollte es Ihnen möglich sein, innerhalb von
Minuten die MySQL-Version auszutauschen!
@xref{Which version}.
@end itemize

@cindex Technischer Support, E-Mail-Adresse
@cindex Support, E-Mail-Adresse
@cindex Kunden-Support, E-Mail-Adresse
@cindex E-Mail-Adresse, für Kunden-Support
Wenn Sie ein Support-Kunde sind, schicken Sie bitte den Bug-Bericht an
@email{mysql-Support@@mysql.com}, damit dieser eine höhere Priorität in der
Bearbeitung erfährt. Schicken Sie ihn gleichzeitig an die entsprechende
Mailing-Liste, um zu sehen, ob schon jemand anderes das selbe Problem hatte
(und vielleicht gelöst hat).

Informationen zu Bug-Berichten siehe @strong{MyODBC} und @ref{ODBC Problems}.

Lösungen für häufig auftretende Probleme siehe @xref{Problems}.

Wenn Ihnen Antworten individuell zugesandt werden und nicht an die
Mailing-Liste, wird es als gute Etikette betrachtet, die Antworten
zusammenzufassen und die Zusammenfassung an die Mailing-Liste zu schicken,
damit andere von den Antworten profitieren können, die Ihnen geholfen
haben, Ihr Problem zu lösen!


@node Answering questions,  , Bug reports, Questions
@c German node Fragen beantworten
@subsubsection Richtlinien für die Beantwortung von Fragen auf der Mailing-Liste

@cindex Netz-Etikette
@cindex Fragen, Antworten
@cindex Fragen beantworten, Etikette
@cindex Mailing-Listen, Richtlinien

Wenn Sie davon ausgehen, dass Ihre Antwort auf breites Interesse stößt,
sollten Sie an die Mailing-Liste posten, statt direkt der Person zu
antworten, die die Frage stellte. Versuchen Sie, Ihre Antwort so allgemein
zu halten, dass auch andere als der ursprünglich Fragende von Ihrer Antwort
profitieren können. Wenn Sie an die Liste posten, stellen Sie bitte sicher,
dass Ihre Antwort kein Duplikat einer vorhergehenden Antwort ist.

Versuchen Sie, den wesentlichen Teil der Frage in Ihrer Antwort
zusammenzufassen. Fühlen Sie sich nicht verpflichtet, die gesamte
ursprüngliche Nachricht zu zitieren.

Bitte schicken Sie Ihre Mailnachrichten nicht im HTML-Format! Viele
Benutzer lesen Nachrichten mit nicht HTML-fähigen Anwendungen!



@node Compatibility, TODO, MySQL Information Sources, Deutsch
@c German node Kompatibilität
@section Wie Standard-kompatibel ist MySQL?

@cindex Kompatibilität mit ANSI SQL
@cindex Standard-Kompatibilität
@cindex Erweiterungen von ANSI SQL
@cindex ANSI SQL92, Erweiterungen


Dieser Abschnitt beschreibt, wie sich MySQL zum ANSI SQL-Standard verhält.
MySQL hat viele Erweiterungen zum ANSI SQL-Standard, und hier steht, welche
das sind und wie man sie benutzt. Hier finden Sie auch Informationen über
Funktionalität, die MySQL fehlt, und wie man mit diesen Unterschieden
umgeht.


@menu
* Standards::                   
* ANSI mode::                   
* Extensions to ANSI::          
* Differences from ANSI::       
* Bugs::                        
@end menu

@node Standards, ANSI mode, Compatibility, Compatibility
@c German node Standards
@subsection An welche Standards hält sich MySQL?

Entry-Level-SQL92. ODBC-Levels 0-2.

Wir beabsichtigen ANSI SQL99 vollständig zu unterstützen. Dies 
wollen wir jedoch keinesfalls auf Kosten von Geschwindigkeit 
oder Codequalität erreichen.

@node ANSI mode, Extensions to ANSI, Standards, Compatibility
@c German node ANSI-Modus
@subsection MySQL im ANSI-Modus laufen lassen

@cindex Laufen lassen, ANSI-Modus
@cindex ANSI-Modus, laufen lassen

Wenn Sie @code{mysqld} mit der @code{--ansi}-Option starten, ändert sich
folgendes Verhalten von MySQL:

@itemize @bullet
@item
@code{||} ist Zeichenketten-Verkettung (Konkatenation) anstelle von
@code{OR}.

@item
Sie können eine beliebige Anzahl von Leerzeichen zwischen Funktionnamen und
@samp{(} eingeben. Das führt zwangsläufig dazu, dass alle Funktionsnamen
als reservierte Wörter behandelt werden.

@item
@samp{"} ist dann ein Quotierungsbezeichner (wie das MySQL-
@samp{`}-Anführungszeichen) und kein Zeichen, dass einen String einschließt.

@item
@code{REAL} wird zu einem Synonym für @code{FLOAT} anstelle eines Synonyms
für @code{DOUBLE}.

@item
Der Standard-Isolationslevel für Transaktionen ist @code{SERIALIZABLE}.
@xref{SET TRANSACTION}.
@end itemize

Das ist dasselbe, als würde man
@code{--sql-mode=REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,SERIALIZE,ONLY_FULL_GROUP_BY}
benutzen.

@node Extensions to ANSI, Differences from ANSI, ANSI mode, Compatibility
@c German node Erweiterungen zu ANSI
@subsection MySQL-Erweiterungen zu ANSI SQL92

@cindex Hinweise
MySQL beinhaltet einige Erweiterungen, die Sie in anderen SQL-Datenbanken
wahrscheinlich nicht finden werden. Passen Sie auf, wenn Sie diese
benutzen, denn Ihr Code ist dann nicht mehr kompatibel mit anderen
SQL-Servern. In einigen Fällen können Sie Code schreiben, der
MySQL-Erweiterungen enthält und dennoch portabel ist, indem Sie Kommentare
in der Form @code{/*! ... */} benutzen. In diesem Fall wird MySQL den Code
innerhalb des Kommentars parsen und ausführen wie jedes andere
MySQL-Statement, aber andere SQL-Server werden die Erweiterungen
ignorieren. Zum Beispiel:

@example
SELECT /*! STRAIGHT_JOIN */ col_name FROM tabelle1, tabelle2 WHERE ...
@end example

Wenn Sie hinter @code{'!'} die Versionsnummer angeben, wird die Syntax nur
ausgeführt, wenn die MySQL-Version gleich oder neuer als die benutzte
Versionsnummer ist:

@example
CREATE /*!32302 TEMPORARY */ TABLE (a int);
@end example

Je höher bedeutet, wenn Sie Version 3.23.02 oder neuer haben, wird MySQL
das @code{TEMPORARY}-Schlüsselwort benutzen.

MySQL-Erweiterungen sind:

@itemize @bullet
@item
Die Feldtypen @code{MEDIUMINT}, @code{SET}, @code{ENUM} und die
unterschiedlichen @code{BLOB}- und @code{TEXT}-Typen.

@item
Die Feldattribute @code{AUTO_INCREMENT}, @code{BINARY}, @code{NULL},
@code{UNSIGNED} und @code{ZEROFILL}.

@item
Alle Zeichenkettenvergleiche achten vorgabemäßig nicht auf
Groß-/Kleinschreibung, wobei die Sortierreihenfolge vom aktuell
verwendeten Zeichensatz abhängig ist (ISO-8859-1 Latin1 als Vorgabe). Wenn
Sie das nicht wollen, sollten Sie Ihre Spalten mit dem
@code{BINARY}-Attribut deklarieren oder den @code{BINARY}-Cast
benutzen, der dafür sorgt, dass Vergleiche mit der ASCII-Sortierung
durchgeführt werden, die der MySQL-Server-Host benutzt.

@item
MySQL legt jede Datenbank als Verzeichnis unterhalb des MySQL-data-
Verzeichnisses an und Tabellen innerhalb einer Datenbank als Dateien in dem
Datenbank-Verzeichnis.

Das hat ein paar Auswirkungen:

@cindex Datenbanknamen, Groß-/Kleinschreibung
@cindex Tabellennamen, Groß-/Kleinschreibung
@cindex Groß-/Kleinschreibung von Datenbanknamen
@cindex Groß-/Kleinschreibung von Tabellennamen

@itemize @minus

@item
Bei Datenbanknamen und Tabellennamen wird auf Unterschiede in der
Groß-/Kleinschreibung geachtet, wenn das Betriebssystem auf
Groß-/Kleinschreibung achtet (wie auf den meisten Unix-Systemen).
@xref{Case sensitivity}.

@item
Datenbank-, Tabellen-, Index-, Spalten- oder Alias-Namen dürfen mit einer
Ziffer beginnen (aber nicht ausschließlich aus Ziffern bestehen).

@item
Sie können Standard-Kommandos des Betriebssystems benutzen, um Tabellen zu
sichern (Datensicherung), umzubenennen, zu verschieben, zu löschen und zu kopieren.
Um zum Beispiel eine Tabelle umzubennen, benennen Sie die Dateien
@file{.MYD}, @file{.MYI} und @file{.frm} um, die der Tabelle entsprechen.
@end itemize

@item
In SQL-Statements können Sie Tabellen aus verschiedenen Datenbanken mit der
@code{db_name.tbl_name}-Syntax ansprechen. Einige SQL-Syntax stellen
dieselbe Funktionalität zur Verfügung, nennen dies aber @code{User space}.
MySQL unterstützt keine Tablespaces wie in folgendem Beispiel:
@code{create tabelle ralph.meine_tabelle...IN mein_tablespace}.

@item
@code{LIKE} ist für numerische Spalten erlaubt.

@item
Die Benutzung von @code{INTO OUTFILE} und @code{STRAIGHT_JOIN} in einem
@code{SELECT}-Statement. @xref{SELECT, , @code{SELECT}}.

@item
Die Option @code{SQL_SMALL_RESULT} in einem @code{SELECT}-Statement.

@item
@code{EXPLAIN SELECT}, um eine Beschreibung zu erhalten, wie Tabellen
verknüpft werden (Join).

@item
Die Benutzung von Index-Namen, Indexen auf ein Prefix eines Feldes, und die
Benutzung von @code{INDEX} oder @code{KEY} in einem @code{CREATE TABLE}-
Statement. @xref{CREATE TABLE, , @code{CREATE TABLE}}.

@item
Die Benutzung von @code{TEMPORARY} oder @code{IF NOT EXISTS} mit @code{CREATE TABLE}.

@item
Die Benutzung von @code{COUNT(DISTINCT list)}, wobei 'list' mehr als ein
Element ist.

@item
Die Benutzung von @code{CHANGE spalten_name}, @code{DROP spalten_name}, oder
@code{DROP INDEX}, @code{IGNORE} oder @code{RENAME} in einem @code{ALTER
TABLE}-Statement. @xref{ALTER TABLE, , @code{ALTER TABLE}}.

@item
Die Benutzung von @code{RENAME TABLE}. @xref{RENAME TABLE, , @code{RENAME TABLE}}.

@item
Die Benutzung mehrfacher @code{ADD}-, @code{ALTER}-, @code{DROP}-, oder
@code{CHANGE}-Klauseln in einem @code{ALTER TABLE} Statement.

@item
Die Benutzung von @code{DROP TABLE} mit the keywords @code{IF EXISTS}.

@item
Sie können mehrere Tabellen löschen mit einem einzigen @code{DROP
TABLE}-Statement.

@item
Die @code{LIMIT}-Klausel des @code{DELETE}-Statements.

@item
Die @code{DELAYED}-Klausel der @code{INSERT}- und @code{REPLACE}-
Statements.

@item
Die @code{LOW_PRIORITY}-Klausel der @code{INSERT}-, @code{REPLACE}-,
@code{DELETE}- und @code{UPDATE}-Statements.

@cindex Oracle-Kompabilität
@cindex Kompatibilität, mit Oracle
@item
Die Benutzung von @code{LOAD DATA INFILE}. In vielen Fällen ist diese
Syntax kompatibel mit Oracles @code{LOAD DATA INFILE}. @xref{LOAD DATA, ,
@code{LOAD DATA}}.

@item
Die @code{ANALYZE TABLE}-, @code{CHECK TABLE}-, @code{OPTIMIZE TABLE}- und
@code{REPAIR TABLE}-Statements.

@item
Das @code{SHOW}-Statement.
@xref{SHOW, , @code{SHOW}}.

@item
Zeichenketten dürfen sowohl durch @samp{"} als auch durch @samp{'}
eingeschlossen werden, nicht nur durch @samp{'}.

@item
Die Benutzung des Escape(@samp{\})Zeichens.

@item
Das @code{SET OPTION}-Statement. @xref{SET OPTION, , @code{SET OPTION}}.

@item
Sie müssen nicht alle ausgewählten Spalten im @code{GROUP BY}-Teil nennen.
Hierdurch ergibt sich eine bessere Performance für einige sehr spezifische,
aber recht gewöhnliche Anfragen.

@item
Man kann @code{ASC} und @code{DESC} bei @code{GROUP BY} spezifizieren.

@item
Um es Benutzern leichter zu machen, die von anderen SQL-Umgebungen kommen,
unterstützt MySQL Aliase für viele Funktionen. Zum Beispiel unterstützen
alle Zeichenketten-Funktionen sowohl die ANSI-SQL-Syntax als auch die
ODBC-Syntax.

@item
MySQL kennt die Operatoren @code{||} und @code{&&}, die logisches Oder und
logisches Und bedeuten, wie in der Programmiersprache C. In MySQL sind
@code{||} und @code{OR} Synonyme, wie auch @code{&&} und @code{AND}.
Aufgrund dieser freundlichen Syntax unterstützt MySQL nicht den
ANSI-SQL-@code{||}-Operator für Zeichenketten-Verkettung (Konkatenation);
benutzen Sie statt dessen @code{CONCAT()}. Weil @code{CONCAT()} eine
beliebige Anzahl von Argumenten entgegennimmt, ist es leicht, die Benutzung
des @code{||}-Operators zu MySQL zu konvertieren.

@item
@code{CREATE DATABASE} oder @code{DROP DATABASE}.
@xref{CREATE DATABASE, , @code{CREATE DATABASE}}.

@cindex PostgreSQL-Kompatibilität
@cindex Kompatibilität, mit PostgreSQL
@item
Der @code{%}-Operator ist ein Synonym für @code{MOD()}. Das heißt @code{N
% M} ist äquivalent zu @code{MOD(N,M)}. @code{%} wird für C-Programmierer
und für Kompatibilität mit PostgreSQL unterstützt.

@item
Die @code{=}-, @code{<>}-, @code{<=}-, @code{<}-, @code{>=}-, @code{>}-,
@code{<<}-, @code{>>}-, @code{<=>}-, @code{AND}-, @code{OR}- oder
@code{LIKE}-Operatoren können in Spaltenvergleichen links von @code{FROM}
in @code{SELECT} Statements benutzt werden. Beispiel:

@example
mysql> SELECT spalte1=1 AND spalte2=2 FROM tabelle_name;
@end example

@item
Die @code{LAST_INSERT_ID()}-Funktion.
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.

@item
Die @code{REGEXP}- und @code{NOT REGEXP}-Operatoren für erweiterte reguläre
Ausdrücke.

@item
@code{CONCAT()} oder @code{CHAR()} mit einem Argument oder mehr als zwei
Argumenten. (In MySQL können diese Funktionen jede beliebige Anzahl von
Argumenten entgegennehmen.)

@item Die Funktionen @code{BIT_COUNT()}, @code{CASE}, @code{ELT()},
@code{FROM_DAYS()}, @code{FORMAT()}, @code{IF()}, @code{PASSWORD()},
@code{ENCRYPT()}, @code{md5()}, @code{ENCODE()}, @code{DECODE()},
@code{PERIOD_ADD()}, @code{PERIOD_DIFF()}, @code{TO_DAYS()} oder
@code{WEEKDAY()}.

@item
Die Benutzung von @code{TRIM()}, um Teile von Zeichenketten zu entfernen.
ANSI SQL unterstützt nur die Entfernung einzelner Zeichen.

@item
Die @code{GROUP BY}-Funktionen @code{STD()}, @code{BIT_OR()} und
@code{BIT_AND()}.

@item
Die Benutzung von @code{REPLACE} anstelle von @code{DELETE} + @code{INSERT}.
@xref{REPLACE, , @code{REPLACE}}.

@item
Das @code{FLUSH flush_option}-Statement.

@item
Die Möglichkeit, Variablen in einem Statement mit @code{:=} zu setzen:
@example
SELECT @@a:=SUM(total),@@b=COUNT(*),@@a/@@b AS avg FROM test_tabelle;
SELECT @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
@end example

@end itemize


@node Differences from ANSI, Bugs, Extensions to ANSI, Compatibility
@c German node Unterschiede zu ANSI
@subsection MySQL-Unterschiede im Vergleich zu ANSI SQL92

Wir versuchen möglichst, dass MySQL dem ANSI-SQL-Standard und dem
ODBC-SQL-Standard folgt, aber in einigen Fällen macht MySQL Dinge auf
andere Weise:

@itemize @bullet
@item
@code{--} ist nur dann ein Kommentar, wenn darauf Whitespace folgt.
@xref{ANSI diff comments}.

@item
Bei @code{VARCHAR}-Spalten werden Leerzeichen am Ende entfernt, wenn der
Wert gespeichert wird. @xref{Bugs}.

@item
In einigen Fällen ändern sich @code{CHAR}-Spalten automatisch (silent) in
@code{VARCHAR}-Spalten. @xref{Silent column changes}.

@item
Zugriffsrechte für eine Tabelle werden nicht automatisch widerrufen, wenn
Sie eine Tabelle löschen. Sie müssen explizit ein @code{REVOKE}-Statement
absetzen, um die Zugriffsrechte für eine Tabelle zu widerrufen.
@xref{GRANT, , @code{GRANT}}.

@item
@code{NULL AND FALSE} werden zu @code{NULL} ausgewertet und nicht zu
@code{FALSE}. Der Grund hierfür liegt darin, dass wir meinen, dass es keine
gute Idee ist, eine Menge von Sonderkonditionen für diesen Fall auswerten
zu müssen.
@end itemize


@menu
* ANSI diff Sub-selects::       
* ANSI diff SELECT INTO TABLE::  
* ANSI diff Transactions::      
* ANSI diff Triggers::          
* ANSI diff Foreign Keys::      
* Beschädigte Fremdschlüssel::  
* ANSI diff Views::             
* ANSI diff comments::          
@end menu

@node ANSI diff Sub-selects, ANSI diff SELECT INTO TABLE, Differences from ANSI, Differences from ANSI
@c German node Fehlende Sub-Selects
@subsubsection Sub-Selects

@cindex Sub-Selects

MySQL unterstützt momentan nur Sub-Selects der Form @code{INSERT
... SELECT ...} und @code{REPLACE ... SELECT ...}. In anderen
Zusammenhängen können Sie allerdings die Funktion @code{IN()} benutzen.

In vielen Fällen können Sie Ihre Anfragen ohne Sub-Selects schreiben:

@example
SELECT * FROM tabelle1 WHERE id IN (SELECT id FROM tabelle2);
@end example

Das kann wie folgt umgeschrieben werden:

@example
SELECT tabelle1.* FROM tabelle1,tabelle2 WHERE tabelle1.id=tabelle2.id;
@end example

Die Anfragen:
@example
SELECT * FROM tabelle1 WHERE id NOT IN (SELECT id FROM tabelle2);
SELECT * FROM tabelle1 WHERE NOT EXISTS (SELECT id FROM tabelle2 where tabelle1.id=tabelle2.id);
@end example

Können wie folgt umgeschrieben werden:

@example
SELECT tabelle1.* FROM tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id where tabelle2.id IS NULL
@end example

Für kompliziertere Unteranfragen (Subqueries) können Sie oft temporäre
Tabelle anlegen, die die Unteranfrage enthalten. In einigen Fällen wird
diese Option allerdings nicht funktionieren. Am häufigsten treten diese
Fälle mit @code{DELETE}-Statements auf, wofür Standard-SQL keine
Verknüpfungen (Joins) unterstützt. Für solche Situationen sind zwei
Optionen verfügbar, solange MySQL noch keine Unteranfragen unterstützt.

Die erste Option besteht darin, eine prozedurale Programmiersprache (wie
PHP oder Perl) zu benutzen, um eine @code{SELECT}-Anfrage zu erhalten, die
die Primärschlüssel enthält, die benötigt werden, um die entsprechenden
Datensätze zu löschen, und dann diese Werte zu benutzen, um das
@code{DELETE}-Statement zu formulieren (@code{DELETE FROM ... WHERE ... IN
(key1, key2, ...)}).

Die zweite Option besteht darin, interaktives SQL zu benutzen, um
automatisch eine Reihe von @code{DELETE}-Statements zu formulieren, indem
die MySQL-Erweiterung @code{CONCAT()} benutzt wird (anstelle des
Standard-Operators @code{||}).
Beispiel:

@example
SELECT CONCAT('DELETE FROM tabelle1 WHERE pkid = ', tabelle1.pkid, ';')
  FROM tabelle1, tabelle2
 WHERE tabelle1.spalte1 = tabelle2.spalte2;
@end example

Sie können diese Anfrage in eine Skriptdatei schreiben und deren Eingabe an
den Kommandozeilen-Interpreter @code{mysql} leiten und von dort die Ausgabe
zurück an eine zweite Instanz des Interpreters:

@example
prompt> mysql --skip-column-names meine_db < mein_skript.sql | mysql meine_db
@end example

MySQL 4.0 unterstützt das Löschen aus mehreren Tabellen (multi-table
deletes), was benutzt werden kann, um effizient Zeilen zu löschen,
basierend auf den Informationen aus einer Tabelle oder sogar aus mehreren
Tabellen zur gleichen Zeit.

@node ANSI diff SELECT INTO TABLE, ANSI diff Transactions, ANSI diff Sub-selects, Differences from ANSI
@c German node Fehlendes SELECT INTO TABLE
@subsubsection @code{SELECT INTO TABLE}

@findex SELECT INTO TABLE

MySQL unterstützt noch nicht die Oracle-SQL-Erweiterung @code{SELECT ...
INTO TABLE ...}.  MySQL unterstützt statt dessen die ANSI-SQL-Syntax
@code{INSERT INTO ... SELECT ...}, die im Prinzip dasselbe ist.
@xref{INSERT SELECT}.

@example
INSERT INTO tabelle_temp2 (fldID) SELECT tabelle_temp1.fldOrder_ID FROM tabelle_temp1 WHERE
tabelle_temp1.fldOrder_ID > 100;
@end example

Alternativ können Sie @code{SELECT INTO OUTFILE...} oder @code{CREATE TABLE
... SELECT} benutzen, um Ihre Probleme zu lösen.


@node ANSI diff Transactions, ANSI diff Triggers, ANSI diff SELECT INTO TABLE, Differences from ANSI
@c German node Fehlende Transaktionen
@subsubsection Transaktionen

@cindex Transaktionen, Support

Weil MySQL heutzutage Transaktionen unterstützt, gelten die folgenden
Erörterungen nur, wenn Sie nur Tabellentypen benutzen, die nicht
transaktionssicher sind. @xref{COMMIT}.

Oft wird von neugierigen oder kritischen Leuten gefragt: ``Warum ist MySQL
keine transaktionale Datenbank?'' oder ``Warum unterstützt MySQL keine
Transaktionen?''

MySQL hat sich bewusst entschieden, andere Paradigmen für die
Datenintegrität zu unterstützen: ``atomische Operationen.'' Es entspricht
unserer Denkweise und unserer Erfahrung, dass atomische Operationen gleiche
oder bessere Integrität bei wesentlich besserer Performance gewährleisten.
Nichtsdestotrotz schätzen und verstehen wir das transaktionale
Datenbank-Paradigma und planen, im Verlauf der nächsten Releases
transaktionssichere Tabellen einzuführen, auf der Basis der
Transaktionssicherheit pro einzelner Tabelle. Wir werden unseren Benutzern
die Entscheidung überlassen, ob Sie in ihren Applikationen den
Geschwindigkeitsvorteil atomischer Operationen benötigen oder die
transaktionalen Features.

Wie benutzt man die Features von MySQL, um rigorose Integrität
beizubehalten, und wie sind diese Features im Vergleich mit dem
transaktionalen Paradigma zu bewerten?

Zunächst ist es nach dem transaktionalen Paradigma bequemer, mit
Transaktionen zu arbeiten, wenn Ihre Applikationen auf eine Weise
geschrieben sind, dass sie in kritischen Situationen ``rollback'' anstelle
von ``commit'' aufrufen. Darüber hinaus stellen Transaktionen sicher, dass
unbeendete Updates oder zerstörende Aktivitäten nicht an die Datenbank
abgesetzt werden; der Server hat die Gelegenheit, ein automatisches
Rollback durchzuführen, wodurch Ihre Datenbank gerettet wird.

In fast allen Fällen erlaubt Ihnen MySQL, potentiellen Problemen
vorzubauen, indem einfache Überprüfungen eingebaut und einfache Skripte
laufen gelassen werden, die die Datenbanken auf Inkonsistenzen prüfen und
automatisch reparieren oder Warnmeldungen ausgeben, wenn so etwas passiert.
Beachten Sie auch, dass allein durch die Benutzung der MySQL-Logdatei oder
durch das Hinzufügen einer speziellen Logdatei Tabellen perfekt repariert
werden können, ohne dass ein Verlust an Datenintegrität eintritt.

Darüber hinaus können fatale transaktionale Updates so umgeschrieben
werden, dass sie atomisch sind. In der Tat gehen wir so weit zu sagen, dass
alle Integritätsprobleme, die Transaktionen lösen, mit @code{LOCK TABLES}
oder atomischen Update durchgeführt werden können, was sicherstellt, dass
Sie nie einen automatischen Abbruch von der Datenbank bekommen, was ein
gewöhnliches Problem transaktionaler Datenbanken darstellt.

Nicht einmal Transaktionen können jeden Verlust verhindern, wenn der Server
abstürzt. In solchen Fällen können sogar transaktionale Systeme Daten
verlieren. Der Unterschied zwischen unterschiedlichen Systemen besteht
einzig darin, wie kurz die Zeitverzögerung ist, in der Daten verloren gehen
könnten. Kein System ist 100%-ig sicher, sondern lediglich ``sicher
genug''. Selbst von Oracle, ansonsten als das sicherste aller
transaktionalen Datenbanken berühmt, wird berichtet, dass es manchmal in
solchen Situationen Daten verliert.

Um mit MySQL auf der sicheren Seite zu sein, brauchen Sie lediglich
Datensicherungen und angeschaltetes Update-Logging. Damit können Sie in
jeder denkbaren Situation genau wie mit jeder beliebigen transaktionalen
Datenbank Daten wiederherstellen. Natürlich ist es immer eine gute Idee,
Datensicherungen zu haben, unabhängig von der verwendeten Datenbank.


Das transaktionale Paradigma hat seine Vor- und Nachteile. Viele
Benutzer und Applikationsentwickler verlassen sich auf die Einfachheit, mit
der sie um Probleme herum Code schreiben können, dort wo anscheinend ein
Abbruch erfolgt ist, oder wo es notwendig ist, haben sie womöglich ein
bisschen mehr Arbeit mit MySQL, weil sie anders denken oder mehr schreiben
müssen. Wenn Ihnen atomische Operationen neu sind oder Sie vertrauter mit
Transaktionen sind (oder Sie sich damit besser fühlen), kommen Sie nicht
gleich zur Schlussfolgerung, dass sich MySQL nicht mit diesen Überlegungen
beschäftigt hat. Zuverlässigkeit und Integrität stehen für uns absolut im
Vordergrund. Aktuelle Schätzungen gehen davon aus, dass zur Zeit mehr als
eine Million @code{mysqld}-Server laufen, von denen viele in
Produktionsumgebungen eingesetzt werden. Wir hören sehr, sehr selten von
Benutzern, die irgendwelche Daten verloren haben, und in fast allen Fällen
sind Benutzerfehler im Spiel. Das ist unserer Meinung nach der beste Beweis
für die Stabilität und Zuverlässigkeit von MySQL.

Im übrigen lassen die aktuellen Features von MySQL Zuverlässigkeit und
Integrität auf Transaktionsebene oder besser zu, wenn in bestimmten
Situationen Integrität von höchster Wichtigkeit ist. Wenn Sie Tabellen mit
@code{LOCK TABLES} sperren, werden alle Updates angehalten, bis jegliche
Integritätsprüfungen durchgeführt sind. Wenn Sie nur eine Lesesperre (Read
Lock) machen (im Gegensatz zu einer Schreibsperre - Write Lock), werden
Lese- und Einfügeoperationen noch zugelassen. Die neu eingefügten
Datensätze können von nicht Clients gesehen werden, die eine
@code{READ}-Sperre haben, bis sie ihre Lesesperre aufheben. Mit
@code{INSERT DELAYED} können Sie Einfügeoperationen in eine lokale
Warteschlange (Local Queue) stellen, solange, bis die Sperren aufgehoben
sind, ohne dass der Client warten muss, bis die Einfügeoperationen
abgeschlossen sind. @xref{INSERT DELAYED}.

``Atomisch'', so wie wir es meinen, ist nichts Magisches. Es bedeutet nur,
dass Sie sicher sein können, dass kein anderer Benutzer mit irgendeinem
laufenden Update in Konflikt kommen kann, und dass es nie ein automatisches
Rollback geben kann (was bei transaktionsbasierenden Systemen vorkommen
kann, wenn Sie nicht sehr vorsichtig sind). MySQL garantiert auch, dass es
keine schmutzigen Lesezugriffe (Dirty Reads) gibt. Sie finden einige
Beispiele, wie man atomische Updates schreibt, im Abschnitt über Commits
und Rollbacks.
@c German FIX This section no longer exists
@c @xref{Commit-Rollback}.

Wir haben reichlich über Integrität und Performance nachgedacht und
glauben, dass unser atomisches Paradigma sowohl Zuverlässigkeit als auch
extrem hohe Performance gewährleistet, und zwar drei- bis fünfmal
schneller, als es die schnellste und optimal eingestellte transaktionale
Datenbank schafft. Wir haben Transaktionen nicht deshalb heraus gelassen,
weil sie schwer zu machen sind. Der Hauptgrund für die Entscheidung für
atomische Operationen gegen Transaktionen liegt darin, dass wir dadurch
viele Geschwindigkeitsoptimierungen machen konnten, die auf andere Art
nicht möglich gewesen wären.

Viele unserer Benutzer, für die Geschwindigkeit das Wichtigste ist, haben
keinerlei Bedenken hinsichtlich Transaktionen. Für sie sind Transaktionen
kein Thema. Diejenigen Benutzer, die Sorgen mit Transaktionen haben oder
sich darüber wundern, dass MySQL diese nicht unterstützt, gibt es eine
``MySQL-Art'', die wir weiter oben beschrieben haben. Denjenigen, denen
Sicherheit wichtiger als Geschwindigkeit ist, empfehlen wir die Benutzung
von @code{BDB}- oder @code{InnoDB}-Tabellen für alle kritischen Daten.
@xref{Table types}.

Ein letzter Hinweis: Wir arbeiten zur Zeit an einem sicheren
Replikationsschema, vom dem wir glauben, dass es besser als jedes
kommerzielle Replikationssystem ist, das wir kennen. Dieses System wird mit
dem atomischen, nicht-transaktionalen Paradigma mit höchster
Zuverlässigkeit laufen. Bleiben Sie dran!


@node ANSI diff Triggers, ANSI diff Foreign Keys, ANSI diff Transactions, Differences from ANSI
@c German node Fehlende Trigger
@subsubsection Gespeicherte Prozeduren und Trigger

@cindex Fehlende Prozeduren und Trigger, Definition
@cindex Prozeduren, gespeicherte
@cindex Trigger, gespeicherte

Eine gespeicherte Prozedur ist ein Satz von SQL-Kommandos, die kompiliert
und auf dem Server gespeichert werden können. Wenn dies einmal geschehen
ist, müssen Clients nicht mehr die gesamte Anfrage absetzen, sondern können
sich auf die gespeicherte Prozedur beziehen. Hiermit wird bessere
Performance erreicht, den die Anfrage muss nur einmal geparst werden, und
es muss weniger Information zwischen Client und Server ausgetauscht werden.
Man kann sogar die konzeptionelle Ebene steigern, indem man Bibliotheken
von Funktionen auf dem Server bereit hält.

Ein Trigger ist eine gespeicherte Prozedur, die aufgerufen wird, wenn ein
bestimmtes Ereignis eintritt. Beispielsweise kann man eine gespeicherte
Prozedur installieren, die jedes Mal ausgeführt wird, wenn ein Datensatz
aus einer Transaktionstabelle gelöscht wird, und die automatisch den dazu
gehörigen Kunden aus einer Kundentabelle löscht, wenn alle seine
Transaktionen gelöscht wurden.

Für ein späteres Release ist geplant, dass MySQL gespeicherte Prozeduren
handhaben kann, aber ohne Trigger. Trigger verlangsamen üblicherweise
alles, sogar Anfragen, für die sie nicht benötigt werden.

Um festzustellen, ab wann MySQL gespeicherte Prozeduren bekommen wird, siehe 
auch @ref{TODO}.


@node ANSI diff Foreign Keys, Beschädigte Fremdschlüssel, ANSI diff Triggers, Differences from ANSI
@c German node Fehlende Fremdschlüssel
@subsubsection Fremdschlüssel

@cindex Fremdschlüssel
@cindex Schlüssel, Fremdschlüssel

Beachten Sie, dass Fremdschlüssel in SQL nicht dazu benutzt werden, um
Tabellen zu verknüpfen, sondern hauptsächlich, um die referentielle
Integrität zu überprüfen (Fremdschlüssel-Restriktionen). Wenn Sie durch ein
@code{SELECT}-Statement Ergebnisse aus mehreren Tabellen erhalten wollen,
tun Sie dies, indem Sie Tabellen verknüpfen (Join):

@example
SELECT * von tabelle1,tabelle2 where tabelle1.id = tabelle2.id;
@end example

@xref{JOIN, , @code{JOIN}}. @xref{example-Foreign keys}.

Die @code{FOREIGN KEY}-Syntax in MySQL existiert nur aus
Kompatibilitätsgründen mit den @code{CREATE TABLE}-Kommandos anderer
Hersteller; sie tut nichts. Die @code{FOREIGN KEY}-Syntax ohne @code{ON
DELETE ...} wird hauptsächlich für Dokumentationszwecke benutzt. Einige
ODBC-Applikationen benutzen dies vielleicht, um automatische
@code{WHERE}-Klauseln zu erzeugen, aber das läßt sich üblicherweise leicht
überschreiben. @code{FOREIGN KEY} wird manchmal als Restriktionsprüfung
benutzt, aber eine solche Überprüfung ist in der Praxis nicht notwendig,
wenn Zeilen in Tabellen in der richtigen Reihenfolge eingefügt werden.
MySQL unterstützt diese Klauseln nur, weil manche Applikationen verlangen,
dass sie existieren (egal ob sie funktionieren oder nicht).

In MySQL können Sie das Problem, dass @code{ON DELETE...} nicht
implementiert ist, dadurch umgehen, dass Sie das entsprechende
@code{DELETE}-Statement einer Applikation hinzufügen, wenn Sie Datensätze
aus einer Tabelle löschen, die Fremdschlüssel hat. In der Praxis ist das
genauso schnell (in einigen Fällen schneller) und wesentlich portabler, als
wenn Sie Fremdschlüssel benutzen würden.

In naher Zukunft werden wir die @code{FOREIGN KEY}-Implementation
erweitern, so dass zumindest die Information in der Datei, die die Tabelle
spezifiziert, gespeichert wird und somit durch @code{mysqldump} und ODBC
abgefragt werden kann. Zu einem späteren Zeitpunkt werden wir
Fremdschlüssel-Restriktionen für Applikationen implementieren, die nicht
leicht durch entsprechendes Programmieren umgangen werden können.



@node Beschädigte Fremdschlüssel, ANSI diff Views, ANSI diff Foreign Keys, Differences from ANSI
@c German node <no English equivalent>
@subsubsection Warum wir Fremdschlüssel nicht implementiert haben

@cindex Fremdschlüssel, warum sie nicht implementiert sind

Viele Leute, die Datenbanken unterrichten und programmieren, sind der
festen Meinung, dass referentielle Integrität durch den Datenbank-Server
erzwungen werden sollte. In der Tat ist dieser Ansatz in vielen Fällen sehr
hilfreich. In vielen Gesprächen mit Datenbankbenutzern haben wir jedoch
festgestellt, dass Fremdschlüssel oft missbraucht werden, was schwer-
wiegende Probleme verursachen kann. Selbst wenn sie in korrekter Weise
benutzt werden, sind sie keine magische Lösung für das Problem
referentieller Integrität, obwohl sie die Dinge in einigen Fällen einfacher
gestalten.

Wegen der obigen Beobachtungen haben wir der Implementation von
Fremdschlüsseln keine hohe Priorität zugewiesen. Unsere Benutzerbasis
bestand bislang zumeist aus Entwicklern, denen es nichts ausmachte,
referentielle Integrität im Code der Applikation zu erzwingen, und die dies
sogar bevorzugten, weil es ihnen mehr Kontrolle gab.

In den letzten Jahren hat sich unsere Benutzerbasis jedoch um einiges
ausgeweitet. Mittlerweile haben wir viele Benutzer, die es schätzen würden,
wenn MySQL erzwungene referentielle Integrität implementiert hätte. Aus
diesem Grund werden wir Fremdschlüssel in naher Zukunft implementieren.
Allerdings können wir zur Zeit noch kein definitives Auslieferungsdatum
nennen.

Einige Vorteile der Erzwingung von Fremdschlüsseln:

@itemize @bullet
@item
Einen sauberen Entwurf der Beziehungen vorausgesetzt machen es
Fremdschlüssel-Restriktionen schwieriger für einen Programmierer,
Inkonsistenzen in eine Datenbank einzuführen.

@item
Wenn kaskadierende Updates und Deletes benutzt werden können, kann dies den
Client-Code vereinfachen.

@item
Sauber entworfene Fremdschlüssel-Regeln sind hilfreich, Beziehungen
zwischen Tabellen zu dokumentieren.
@end itemize

Nachteile:

@itemize @bullet
@item
MySQL unterstützt noch keine erzwungene referentielle Integrität. Wenn Ihre
Applikation also davon abhängt, können Sie sie solange nicht mit MySQL
benutzen, bis wir dieses Feature implementieren.

@item
Fehler, die beim Entwurf von Schlüsselbeziehungen leicht zu machen sind,
können schwer wiegende Probleme verursachen, zum Beispiel Zirkelbezüge oder
eine falsche Kombination kaskadierender Deletes.

@item
Eine sauber geschriebene Applikation wird intern sicherstellen, dass sie
referentielle Integritäts-Restriktionen nicht verletzt, bevor sie mit einer
Anfrage fortfährt. Deshalb werden zusätzliche Überprüfungen auf
Datenbankebene solche Applikationen nur verlangsamen.

@item
Es ist nichts Ungewöhnliches, dass ein Datenbankadministrator eine so
komplexe Topologie von Beziehungen einführt, dass es sehr schwierig, wenn
nicht gar unmöglich wird, einzelne Tabellen zu sichern oder
wiederherzustellen.
@end itemize


@node ANSI diff Views, ANSI diff comments, Beschädigte Fremdschlüssel, Differences from ANSI
@c German node Fehlende Sichten
@subsubsection Sichten (Views)

@cindex Sichten (Views)

MySQL unterstützt noch keine Sichten, aber wir planen, diese in Version 4.1
zu implementieren.

Sichten sind äußerst nützlich, um Benutzern Zugang zu einem Satz von
Beziehungen wie zu einer einzigen Tabelle zu gewähren (Lesezugriff). Viele
SQL-Datenbanken lassen es nicht zu, dass irgend welche Zeilen in einer
Sicht aktualisiert werden (Update). Statt dessen müssen die einzelnen
Tabellen aktualisiert werden.

Weil MySQL meist in Applikationen und in Web-Systemen eingesetzt werden, wo
der Applikationsprogrammierer volle Kontrolle über die Datenbankbenutzung
hat, sehen die meisten unserer Benutzer Sichten als nicht sehr wichtig an.
(Zumindest war niemand interessiert genug, um die Implementation von
Sichten zu finanzieren.)

In MySQL werden Sichten nicht benötigt, um den Zugriff auf Spalten zu
beschränken, weil MySQL ein sehr ausgefeiltes System der
Zugriffsberechtigungen hat. @xref{Privilege system}.


@node ANSI diff comments,  , ANSI diff Views, Differences from ANSI
@c German node Fehlende Kommentare
@subsubsection @samp{--} als Beginn eines Kommentars

@cindex Kommentare, Beginn
@cindex Beginn, Kommentar

Einige andere SQL-Datenbanken benutzen @samp{--}, um Kommentare zu
beginnen. MySQL benutzt @samp{#} als Anfangszeichen, wenn auch das
@code{mysql}-Kommandozeilen-Werkzeug alle Zeilen entfernt, die mit @samp{--}
anfangen. Sie können in MySQL auch Kommentare im C-Stil verwenden @code{/*
Das ist ein Kommentar */}. @xref{Comments}.

MySQL ab Version 3.23.3 unterstützt Kommentare, die mit @samp{--} beginnen,
allerdings nur, wenn der Kommentarbeginn von einem Leerzeichen gefolgt
wird. Der Grund liegt darin, dass dieser degenerierte Kommentar-Stil eine
Menge Probleme mit automatisch generierten SQL-Anfragen verursacht, die
Ähnliches wie den folgenden Code benutzen, wo automatisch der Wert einer
Zahlung für @code{!zahlung!} eingefügt wird:

@example
UPDATE tabelle_name SET kredit=kredit-!zahlung!
@end example

Was, glauben Sie, passiert, wenn der Wert von @code{zahlung} negativ wird?

Weil @code{1--1} in SQL zulässig ist, sind wir der Meinung, dass es
furchtbar ist, dass @samp{--} den Anfang eines Kommentars bedeutet.

In MySQL ab Version 3.23 können Sie allerdings folgendes benutzen:
@code{1-- Das ist ein Kommentar}

Die folgenden Erörterungen treffen nur zu, wenn Sie eine MySQL-Version vor
3.23 laufen lassen:

Wenn Sie ein SQL-Programm in einer Textdatei haben, das @samp{--}-Kommentare
enthält, sollten Sie folgendes benutzen:

@example
shell> replace " --" " #" < text-datei-mit-merkwuerigen-kommentaren.sql \
         | mysql datenbank
@end example

anstelle des üblichen:

@example
shell> mysql datenbank < text-datei-mit-merkwuerdigen-kommentaren.sql
@end example

Sie können auch die Kommandodatei ``direkt'' editieren, um die
@samp{--}-Kommentare zu @samp{#}-Kommentaren zu machen:

@example
shell> replace " --" " #" -- text-datei-mit-merkwuerdigen-kommentaren.sql
@end example

Machen Sie die Änderungen mit folgendem Befehl rückgängig:

@example
shell> replace " #" " --" -- text-datei-mit-merkwuerdigen-kommentaren.sql
@end example



@node Bugs,  , Differences from ANSI, Compatibility
@c German node Bugs
@subsection Bekannte Fehler und Design-Unzulänglichkeiten in MySQL

@cindex Bugs, bekannte
@cindex Fehler, bekannte
@cindex Design, Probleme
@cindex Bekannte Fehler

Die folgenden Probleme sind bekannt. Ihre Behebung hat eine sehr hohe
Priorität:

@itemize @bullet
@item
@code{ANALYZE TABLE} kann eine BDB-Tabelle in manchen Fällen unbenutzbar
machen, bis @code{mysqld} neu gestartet wird. Wenn so etwas passiert,
stehen Fehlermeldungen wie die folgende in der MySQL-Fehler-Datei (Error
File):

@example
001207 22:07:56  bdb:  log_flush: LSN past current end-of-log
@end example

@item
Führen Sie mit einer @code{BDB}-Tabelle nicht @code{ALTER TABLE} aus, wenn
Sie mit dieser noch nicht abgeschlossene Mehrfach-Statement-Transaktionen
durchführen. (Die Transaktion wird wahrscheinlich ignoriert.)

@item
@code{ANALYZE TABLE}, @code{OPTIMIZE TABLE} und @code{REPAIR TABLE} können
Probleme bei Tabellen verursachen, für die @code{INSERT DELAYED} benutzt
wird.

@item
Wenn Sie @code{LOCK TABLE ..} und @code{FLUSH TABLES ..} benutzen, können
Sie nicht sicher sein, dass bei der fraglichen Tabelle keine halb
abgeschlossenen Transaktionen im Gange sind.

@item
BDB-Tabellen lassen sich etwas langsam öffnen. Wenn Sie viele BDB-Tabellen
in einer Datenbank haben, kann es sehr lange dauern, bis Sie den
@code{mysql}-Client für diese Datenbank benutzen können, wenn Sie die
@code{-A}-Option oder @code{rehash} benutzen. Das macht sich speziell dann
bemerkbar, wenn Sie einen große Tabellen-Cache benutzen.

@item
Das momentane Replikationsprotokoll kann nicht mit @code{LOAD DATA INFILE}
und mit Zeilenbegrenzungszeichen (line terminator characters) umgehen, die
mehr als 1 Zeichen enthalten.
@end itemize

Folgende Probleme sind bekannt und werden zu gegebener Zeit behoben:
@itemize @bullet
@item
Momentan funktioniert @code{MATCH} nur bei @code{SELECT}-Statements.

@item
Wenn Sie @code{SET CHARACTER SET} benutzen, können Sie keine
landesspezifischen (nationalen) Zeichen für Datenbank-, Tabellen- und
Spaltennamen verwenden (also z. B. kein ä, ö, ü).

@item
@code{DELETE FROM merge_table} ohne @code{WHERE} löscht nur die Zuordnung
(das Mapping) für die Tabelle, nicht alles in der zugeordneten (gemappten)
Tabelle.

@item
Sie können den Server nicht in ein anderes Verzeichnis bauen, wenn Sie
MIT-Pthreads verwenden. Weil dies Änderungen an MIT-Pthreads bedingen
würde, werden wir dieses Problem wahrscheinlich nicht beheben.

@item
@code{BLOB}-Werte können nicht ``zuverlässig'' in @code{GROUP BY}-,
@code{ORDER BY} oder @code{DISTINCT}-Klauseln benutzt werden. In diesen
Fällen werden bei Vergleichen nur die ersten @code{max_sort_length}
Bytes (Vorgabewert 1024) von @code{BLOB}s benutzt. Die Voreinstellung kann
mit der @code{-O max_sort_length}-Option für @code{mysqld} geändert werden.
In den meisten Fällen können Sie als Workaround eine Teilzeichenkette
(Substring) verwenden: @code{SELECT DISTINCT LEFT(blob,2048) FROM
tabelle}.

@item
Berechnungen werden mit @code{BIGINT} oder @code{DOUBLE} durchgeführt
(beide sind normalerweise 64 Bits lang). Es hängt von der verwendeten
Funktion ab, welche Genauigkeit man erhält. Als allgemeine Regel gilt, dass
Bit-Funktionen mit @code{BIGINT}-Genauigkeit, @code{IF} und @code{ELT()}
mit @code{BIGINT}- oder @code{DOUBLE}-Genauigkeit und der Rest mit
@code{DOUBLE}-Genauigkeit durchgeführt werden. Man sollte vermeiden,
vorzeichenlose Werte, die größer als 63 Bits sind (9223372036854775807),
zu verwenden, ausser für Bit-Felder!
MySQL 4.0 bietet eine bessere @code{BIGINT}-Handhabung als MySQL 3.23.

@item
Bei allen Zeichenketten-Spalten ausser bei @code{BLOB}- und
@code{TEXT}-Spalten werden Leerzeichen am Ende automatisch entfernt, wenn
sie abgerufen werden. Bei @code{CHAR}-Typen ist das okay und kann gemäß
ANSI-SQL92 als ein Feature betrachtet werden. Der Bug besteht darin, dass
in MySQL auch @code{VARCHAR}-Spalten auf dieselbe Art behandelt werden.

@item
Pro Tabelle können höchstens 255 @code{ENUM}- und @code{SET}-Spalten
verwendet werden.

@item
@code{safe_mysqld} leitet alle Nachrichten von @code{mysqld} in die
@code{mysqld}-Logdatei um. Ein Problem ergibt sich, wenn Sie
@code{mysqladmin refresh} benutzen, um die Logdatei zu schließen und
wieder zu öffnen. In diesem Fall werden @code{stdout} und @code{stderr}
immer noch in die alte Logdatei geleitet.
Wenn Sie @code{--log} umfangreich benutzen, sollten Sie @code{safe_mysqld}
editieren, um in @file{'hostname'.err} anstelle von @file{'hostname'.log}
zu loggen, damit Sie den Speicherplatz für das alte Log leicht neu belegen
können, indem Sie das alte Log löschen und @code{mysqladmin refresh}
ausführen.

@item
Im @code{UPDATE}-Statement, werden Spalten von links nach rechts
aktualisiert (Update). Wenn Sie sich auf eine aktualisierte Spalte
beziehen, erhalten Sie den aktualisierten Werte anstelle des ursprünglichen
Werts. Beispiel:

@example
mysql> UPDATE tabelle SET KEY=KEY+1,KEY=KEY+1;
@end example

Dieses Statement aktualisiert @code{KEY} mit @code{2} anstelle von
@code{1}.

@item
Sie können temporäre Tabellen nicht öfter als einmal innerhalb derselbe
Anfrage benutzen. Das Folgende zum Beispiel funktioniert nicht:

@example
select * from temporaere_tabelle, temporaere_tabelle as t2;
@end example

@item
@code{RENAME} funktioniert nicht bei @code{TEMPORARY}-Tabellen.

@item
Unter Umständen behandelt der Optimierer (Optimizer) @code{DISTINCT}
unterschiedlich, je nachdem, ob Sie 'versteckte' Spalten in einem Join
benutzen oder nicht. In einem Join werden versteckte Spalten als Teil des 
Ergebnisses gezählt (selbst wenn sie nicht angezeigt werden), während 
versteckte Spalten in normalen Anfragen nicht an einem @code{DISTINCT}-Vergleich 
teilnehmen. Zukünftig werden wir dieses Verhalten wahrscheinlich ändern, so 
dass versteckte Spalten nie verglichen werden, wenn @code{DISTINCT} ausgeführt 
wird.

Hierfür ein Beispiel:

@example
SELECT DISTINCT mp3id FROM band_downloads WHERE userid = 9 ORDER BY id
DESC;
@end example

und

@example
SELECT DISTINCT band_downloads.mp3id, FROM band_downloads,band_mp3
WHERE band_downloads.userid = 9 AND band_mp3.id = band_downloads.mp3id
ORDER BY band_downloads.id DESC;
@end example

Im zweiten Fall bekommen Sie in MySQL 3.23.x möglicherweise zwei identische
Zeilen in der Ergebnismenge (weil die versteckten 'id'-Spalten
unterschiedlich sein können).

Beachten Sie, dass dies nur für Anfragen zutrifft, bei denen die ORDER
BY-Spalten nicht im Ergebnis enthalten sind. ANSI-SQL erlaubt dies nicht

@item
Weil MySQL es zuläßt, mit Tabellentypen zu arbeiten, die keine
Transaktionen unterstützen (und folglich Daten nicht per @code{rollback} in
den vorherigen Zustand bringen können), verhalten sich einige Dinge in
MySQL etwas anderes als in anderen SQL-Servern. Das kann manchmal etwas
ungünstig sein, weil Spaltenwerte in der Applikation überprüft werden
müssen. Auf der anderen Seite erhalten Sie dadurch eine nette
Geschwindigkeitssteigerung, weil es MySQL gestattet, einige Optimierungen
vorzunehmen, die ansonsten sehr schwer durchzuführen sein würden.

Wenn Sie eine Spalte auf einen nicht zulässigen Wert setzen, speichert
MySQL, statt ein Rollback durchzuführen, den @code{besten möglichen Wert}
in der Spalte:

@itemize @minus
@item
Wenn Sie versuchen, in einer numerischen Spalte einen Wert ausserhalb des
Wertebereichs zu speichern, speichert MySQL statt dessen den kleinsten oder
größten möglichen Wert.

@item
Wenn Sie versuchen, eine Zeichenkette, die nicht mit einer Zahl beginnt, in
einer numerischen Spalte zu speichern, speichert MySQL 0.

@item
Wenn Sie versuchen, @code{NULL} in einer Spalte zu speichern, die keine
@code{NULL}-Werte zuläßt, speichert MySQL 0 oder @code{''} (leere
Zeichenkette). (Man kann dieses Verhalten jedoch mit der
-DDONT_USE_DEFAULT_FIELDS-Kompilierungs-Option ändern.)

@item
MySQL läßt zu, dass einige falsche Datumswerte in @code{DATE}- und
@code{DATETIME}-Spalten gespeichert werden (wie 2000-02-31 oder
2000-02-00). Wenn das Datum völlig falsch ist, speichert MySQL den
speziellen Datumswert 0000-00-00 in der Spalte.

@item
Wenn Sie @code{enum} auf einen nicht unterstützten Wert setzen, wird es auf
den Fehlerwert 'leere Zeichenkette' oder (bei numerischen Werten) auf 0
gesetzt.
@end itemize

@item
Wenn Sie @code{PROCEDURE} auf eine Anfrage ausführen, die eine leere
Ergebnismenge liefert, kann es in einigen Fällen vorkommen, dass
@code{PROCEDURE} die Spalten nicht umwandelt.

@item
Wenn Sie eine Tabelle vom Typ @code{MERGE} anlegen, wird nicht überprüft,
ob die zugrunde liegenden Tabellen von einem kompatiblen Typ sind.

@item
MySQL kann bislang nicht mit @code{NaN}-, @code{-Inf}- und
@code{Inf}-Werten in Doubles umgehen. Wenn Sie diese benutzen, gibt es
Probleme, wenn Daten importiert oder exportiert werden. Als Zwischenlösung
sollten Sie @code{NaN} in @code{NULL} umwandeln (falls möglich) und
@code{-Inf} und @code{Inf} in den kleinsten bzw. größten möglichen Wert.

@item
Negative Zahlen in der @code{LIMIT}-Klausel werden als große positive
Zahlen behandelt.

@item
Wenn Sie @code{ALTER TABLE} benutzen, um einen @code{UNIQUE}-Index zu einer
Tabelle hinzuzufügen, die in einer @code{MERGE}-Tabelle benutzt wird, und
dann @code{ALTER TABLE} benutzen, um der @code{MERGE}-Tabelle einen
normalen Index hinzuzufügen, weicht die Reihenfolge der Schlüssel für die
Tabellen ab. Das liegt daran, dass @code{ALTER TABLE}
@code{UNIQUE}-Schlüssel vor normalen Schlüsseln einfügt, um doppelte
Schlüssel so früh wie möglich erkennen zu können.
@end itemize

Folgende bekannte Bugs gibt es in früheren Versionen von MySQL:

@itemize @bullet
@item
Man kann einen hängenden Thread erhalten, wenn man @code{DROP TABLE} auf
eine Tabelle ausführt, die zu vielen Tabellen gehört, die mit @code{LOCK
TABLES} gesperrt sind.

@item
In folgenden Fällen können Sie einen Core Dump erhalten:

@itemize @minus
@item
Die Routine für verzögertes Einfügen (Delayed Insert Handler) hat noch nie
ausgeführte Einfügeoperationen (Pending Inserts) auf eine Tabelle.

@item
@code{LOCK tabelle} mit @code{WRITE}

@item
@code{FLUSH TABLES}
@end itemize

@item
Vor MySQL-Version 3.23.2 kann ein @code{UPDATE} fehlschlagen, dass einen
Schlüssel mit einer @code{WHERE}-Klausel auf denselben Schlüssel
aktualisiert, weil der Schlüssel benutzt wurde, um nach Datensätzen zu
suchen, und dieselbe Zeile mehrfach gefunden wurde:

@example
UPDATE tabelle SET KEY=KEY+1 WHERE KEY > 100;
@end example

Ein Workaround besteht in der Benutzung von:

@example
mysql> UPDATE tabelle SET KEY=KEY+1 WHERE KEY+0 > 100;
@end example

Das funktioniert, weil MySQL auf Ausdrücke (Expressions) in der
@code{WHERE}-Klausel keine Indizes benutzt.

@item
Vor MySQL-Version 3.23 wurden alle numerischen Typen als Festkomma-Felder
behandelt. Das bedeutet, dass Sie festlegen müssen, wie viele
Dezimalstellen ein Fließkomma-Feld haben soll. Alle Werte wurden mit der
korrekten Anzahl von Dezimalstellen zurückgegeben.
@end itemize

Was Plattform-spezifische Bugs angeht, sehen Sie bitte im Abschnitt über
Kompilieren und Portieren nach.


@node TODO, Comparisons, Compatibility, Deutsch
@c German node TODO
@section MySQL und die Zukunft (das TODO)

@cindex TODO-Liste für MySQL


Dieser Anhang listet die Features auf, für die wir eine Implementierung in
MySQL geplant haben.

Alles auf dieser Liste gibt nur ungefähr die Reihenfolge wieder, in der es
gemacht werden wird. Wenn Sie die Prioritäten beeinflussen wollen,
registrieren Sie bitte eine Lizenz oder unterstützen Sie uns und teilen uns
mit, was Sie schneller gemacht haben wollen. @xref{Lizenzpolitik}.

Geplant ist, dass wir in Zukunft den kompletten ANSI-SQL99-Standard
unterstützen, aber mit einer Menge nützlicher Erweiterungen. Die
Herausforderung liegt darin, dass durchzuführen, ohne
Geschwindigkeitsvorteile zu opfern oder den Code zu kompromittieren.


@menu
* TODO MySQL 4.0::              
* TODO future::                 
* TODO sometime::               
* TODO unplanned::              
@end menu

@node TODO MySQL 4.0, TODO future, TODO, TODO
@c German node TODO MySQL 4.0
@subsection Dinge, die in Version 4.0 enthalten sein sollten

Wir haben uns der Entwicklung von MySQL Version 4.0 zugewandt. Die meisten
grundsätzlichen Dinge, die wir in Version 4.0 haben wollen, sind bereits
gemacht. Das Ziel ist, den Rest der folgenden Features schnell einzubauen
und dann zur Entwicklung von MySQL 4.1 überzugehen.
@c German FIX Added . after @xref.
@xref{MySQL 4.0 In A Nutshell}.

Der News-Abschnitt für 4.0 beinhaltet eine Liste der Features, die wir
bereits im 4.0-Baum implementiert haben. @xref{News-4.0.x}.

@itemize @bullet
@item
Benutzern erlauben, die Startoptionen zu ändern, ohne den Server herunter
fahren zu müssen.
@item
Störsichere Replikation.
@item
Mehr Funktionen für die Volltextsuche.
@xref{Volltext-Features in MySQL 4.0}.
@item
Neuer Schlüssel-Cache
@item
Neues Dateiformat für die Tabellendefinition (@code{.frm}-Dateien). Das
versetzt uns in die Lage, nicht irgendwann keine Bits mehr zu haben, wenn
wir weitere Tabellenoptionen hinzufügen. Es wird nach wie vor möglich sein,
in 4.0 das alte @code{.frm}-Dateiformat zu benutzen. Alle neu erzeugten
Tabellen werden jedoch das neue Format benutzen.

Das neue Dateiformat versetzt uns in die Lage, neue Spaltentypen, mehr
Optionen für Schlüssel und @code{FOREIGN KEY}-Support hinzuzufügen.
@item
Die Replikation sollte mit @code{RAND()} und Benutzer-Variablen
@code{@@var} funktionieren.
@item
Online-Datensicherung mit sehr geringen Performance-Einbussen. Das Online-Backup
wird das Hinzufügen eines neuen Replikations-Slaves erleichtern, ohne dass
man den Master herunter fahren muss.
@item
Es zulassen, dass @code{DELETE} auf @code{MyISAM}-Tabellen den
Datensatz-Cache benutzt. Um das zu tun, müssen wir den Thread-Cache für
Datensätze aktualisieren, wenn wir die @code{.MYD}-Datei aktualisieren.
@item
Zeichensatz-Festlegungen (Casts) und Syntax für die Handhabung mehrerer
Zeichensätze.
@item
Hilfe für alle Befehle des Clients.
@item
Sichere Verbindungen (mit SSL).
@item
@code{SHOW COLUMNS FROM tabelle} (der vom @code{mysql}-Client benutzt für
die Erweiterung von Spaltennamen benutzt wird) sollte nicht die Tabelle
öffnen, sondern nur die Definitionsdatei. Das wird weniger Speicher
beanspruchen und sehr viel schneller sein.
@item
Bei der Benutzung von @code{SET CHARACTER SET} sollten wir die gesamte
Anfrage übersetzen und nicht nur Zeichenketten. Das würde Benutzern
ermöglichen, landesspezifische Zeichen auch in Datenbank-, Tabellen- und
Spaltenamen zu benutzen.
@item
Hinzufügen einer portablen Schnittstelle zu @code{gethostbyaddr_r()},
damit wir @code{ip_to_hostname()} davon abhalten können, andere Threads zu
blockieren, während es DNS-Lookups durchführt.
@item
Hinzufügen der @code{record_in_range()}-Methode zu @code{MERGE}-Tabellen,
um den richtigen Index auswählen zu können, wenn es viele gibt, aus denen
ausgewählt werden kann. Wir sollten auch die info-Schnittstelle erweitern,
um die Schlüsselverteilung für jeden Index zu erhalten, wenn @code{analyze}
über alle Unter-Tabellen läuft.
@item
@code{SET SQL_DEFAULT_TABLE_TYPE=[MyISAM | INNODB | BDB | HEAP]}.
@end itemize


@node TODO future, TODO sometime, TODO MySQL 4.0, TODO
@c German node TODO zukünftig
@subsection Dinge, die in naher Zukunft erledigt werden müssen

@itemize @bullet
@item
Unteranfragen (Subqueries).
@code{select id from t where grp in (select grp from g where u > 100)}
@item
Atomische Multi-Tabellen-Updates, zum Beispiel @code{update items,month set
items.price=month.price where items.id=month.id;};
@item
Abgeleitete Tabellen (Derived Tables).
@example
select a.col1, b.col2 from (select max(col1) as col1 from root_table ) a,
other_table b where a.col1=b.col1
@end example

Das könnte erreicht werden, indem für die Dauer der Anfrage automatisch
temporäre Tabellen für die abgeleiteten Tabellen erzeugt werden.
@item
Hinzufügen eines @code{PREPARE} von Statements und Senden von Parametern an
@code{mysqld}.
@item
Erweiterung des Client-Server-Protokolls, um Warnungen (Warnings) zu
unterstützen.
@item
Hinzufügen von Optionen zum Client-Server-Protokoll, um
Fortschrittsanzeigen für lange laufende Kommandos zu erhalten.
@item
Hinzufügen von Datenbank und echtem Tabellennamen (im Falle von Alias) zur
MYSQL_FIELD-Struktur.
@item
Nicht mehr als die festgelegte Anzahl von Threads zulassen, um MyISAM
recover zeitgleich laufen zu lassen.
@item
@code{INSERT ... SELECT} ändern, um optional konkurrierende Inserts zu
benutzen.
@item
@code{RENAME DATABASE} implementieren. Damit das sicher für alle
Tabellen-Handler funktioniert, sollte es wie folgt laufen:
@itemize @bullet
@item
Neue Datenbank anlegen.
@item
Für jede Tabelle ein Umbenennen der Tabelle zu einer anderen Datenbank
durchführen, wie wir es schon mit dem @code{RENAME}-Befehl machen.
@item
Alte Datenbank löschen.
@end itemize
@item
Die Original-Feldtypen zurückgeben, wenn @code{SELECT MIN(column)... GROUP
BY} ausgeführt wird.
@item
Mehrfache Ergebnismengen (Multiple Result Sets).
@item
Änderung des Protokolls, um Binärübertragung von Werten zu ermöglichen. Um
das effizient zu machen, müssen wir eine API hinzufügen, die Bindung
(Binding) von Variablen erlaubt.


@code{mysqld}.
@item
Es soll möglich sein, @code{long_query_time} mit einer Auflösung in
Mikrosekunden festzulegen.
@item
Hinzufügen eines konfigurierbaren Prompts zum
@code{mysql}-Kommandozeilen-Werkzeug, mit Optionen wie Datenbank in Benutzung,
Zeit und Datum ...
@item
Hinzufügen von Bereichsüberprüfung (Range Checking) zu
@code{MERGE}-Tabellen.
@item
@code{myisampack}-Code in den Server einlinken.
@item
Portierung von MySQL auf BeOS.
@item
Portierung von MySQL-Clients auf LynxOS.
@item
Hinzufügen eines temporären Schlüssel-Puffer-Caches während
@code{INSERT/DELETE/UPDATE}, um den vorherigen Zustand elegant
wiederherstellen zu können, wenn der Index voll wird.
@item
Wenn ein @code{ALTER TABLE} auf eine Tabelle durchgeführt wird, die per
Symlink auf einer anderen Festplatte ist, temporäre Tabellen auf dieser
Festplatte erzeugen.
@item
Implementierung eines @code{DATE/DATETIME}-Typs, der
Zeitzonen-Informationen sauber handhabt, damit der Umgang mit Datumswerten
in verschiedenen Zeitzonen leichter wird.
@item
FreeBSD- und MIT-pThreads; nehmen schlafende Threads CPU in Anspruch?
@item
Prüfen, ob gesperrte Threads CPU beanspruchen.
@item
Configure reparieren, so dass man alle Bibliotheken (wie @code{MyISAM})
ohne Threads kompilieren kann.
@item
Hinzufügen einer Option, um regelmäßig die Schlüsselseiten (Key Pages) für
Tabellen mit verzögerten Schlüsseln (Delayed Keys) zu löschen (flush), wenn
Sie eine Weile nicht in Gebrauch waren.
@item
Verknüpfungen (Join) auf Teile des Schlüssels zulassen (Optimierungsthema).
@item
@code{INSERT SQL_CONCURRENT} und @code{mysqld --concurrent-insert} sollen
ein konkurrierendes Insert am Ende der Datei machen, falls die Datei
lese-gesperrt ist.
@item
@code{FOREIGN}-Key-Festlegungen in der @file{.frm}-Datei speichern.
@item
Kaskadierendes Löschen (@code{DELETE})
@item
Serverseitige Cursor.
@item
Prüfen, ob @code{lockd} mit modernen Linux-Kernels funktioniert; wenn
nicht, müssen wir @code{lockd} überarbeiten! Um das zu testen, startet man
@code{mysqld} mit @code{--enable-locking} und läßt die verschiedenen fork*
test suits laufen. Sie sollten keine Fehler produzieren, wenn @code{lockd}
funktioniert.
@item
SQL-Variablen in @code{LIMIT} zulassen, wie @code{LIMIT @@a,@@b}.
@item
Aktualisierung von Variablen in @code{UPDATE}-Statements zulassen, zum
Beispiel: @code{UPDATE TABLE foo SET @@a=a+b,a=@@a, b=@@a+c}
@item
Wenn Benutzervariablen aktualisiert werden, so ändern, dass man sie mit
@code{GROUP BY} benutzen kann wie in folgendem Beispiel:
@code{SELECT id, @@a:=count(*), sum(sum_col)/@@a FROM tabelle GROUP BY id}.
@item
Keine automatischen @code{DEFAULT}-Werte zu Spalten hinzufügen. Fehler
ausgeben, wenn ein @code{INSERT} benutzt wird, dass keine Spalte enthält,
die keinen @code{DEFAULT}-Wert hat.
@item
Caching von Anfragen und Ergebnissen. Das sollte als separates Modul
gemacht werden, das jede Anfrage prüft. Falls diese Anfrage im Cache ist,
soll das Cache-Ergebnis zurückgegeben werden. Wenn man eine Tabelle
aktualisiert, sollte man so wenige Anfragen wie möglich aus dem Cache
entfernen. Das sollte eine große Geschwindigkeitssteigerung auf Maschinen
geben, die viel RAM haben und wo Anfragen of wiederholt werden (wie
WWW-Applikationen). Eine Idee wäre, nur Anfrage des Typs
@code{SELECT CACHED ...}
zu cachen.
@item
@file{libmysql.c} überarbeiten, damit zwei @code{mysql_query()}-Befehle in
einer Zeile stehen können, ohne dass Ergebnisse gelesen werden oder man
eine nette Fehlermeldung erhält, wenn man das tut.
@item
Optimierung des @code{BIT}-Typs, so dass er 1 Bit aufnimmt (momentan nimmt
@code{BIT} 1 Zeichen auf).
@item
Prüfen, warum MIT-pThreads @code{ctime()} auf einigen FreeBSD-Systemen
nicht funktioniert.
@item
Hinzufügen einer @code{IMAGE}-Option zu @code{LOAD DATA INFILE}, damit
@code{TIMESTAMP}- und @code{AUTO_INCREMENT}-Felder nicht aktualisiert
werden.
@item
@code{LOAD DATE INFILE.. UPDATE}-Syntax hinzufügen.
@itemize @bullet
@item
Wenn Daten bei Tabellen mit Primärschlüssel den Primärschlüssel enthalten,
werden Einträge, die zu diesem Primärschlüssel passen, vom Rest der Spalten
aktualisert. Spalten, die im herein kommenden Datenstrom NICHT enthalten
sind, werden jedoch nicht berührt.
@item
Bei Tabellen mit Primärschlüsseln, wo im herein kommenden Datenstrom ein
Teil des Schlüssels fehlt, oder wenn kein Primärschlüssel eingegeben wird,
wird die Eingabe so behandelt wie jetzt schon @code{LOAD DATA INFILE ...
REPLACE INTO}.
@end itemize
@item
@code{LOAD DATA INFILE} soll auch folgende Syntax verstehen:
@example
LOAD DATA INFILE 'datei.txt' INTO TABLE tabelle
TEXT_FIELDS (text_feld1, text_feld2, text_feld3)
SET tabelle_feld1=concatenate(text_feld1, text_feld2), tabelle_feld3=23
IGNORE text_feld3

Das kann benutzt werden, um zusätzliche Spalten in der Textdatei zu
überspringen oder um Spalten basierend auf Ausdrücken in den gelesenen
Daten zu aktualisieren ...
@end example
@item
@code{LOAD DATA INFILE 'datei' INTO TABLE 'tabelle' ERRORS TO err_tabelle}
Das würde bewirken, dass alle Fehler und Warnungen in der err_tabelle
mitgeschrieben werden. Diese Tabelle hätte etwa folgende Struktur:

@example
zeile_nummer     - Zeilennummer in der Datendatei
fehler_nachricht - die Fehler-/Warnungs-Nachricht
und vielleicht
@c German FIX changed all "@cQuestion ..." lines to "@c Question ..." (space).
@c Question: ??? This is already logged in zeile_nummer (line_number)!
daten_zeile      - die Zeilennummer der Datendatei
@end example
@item
Hinzufügen von echter @code{VARCHAR}-Unterstützung (gibt es schon in
MyISAM).
@item
Automatische Ausgabe von @code{mysql} an Netscape.
@item
@code{LOCK DATABASES}. (mit vielerlei Optionen)
@item


Ändern wie Sortierung Speicher alloziert, um bessere
Speicherausnutzung zu erhalten.
@item
@code{DECIMAL}- und @code{NUMERIC}-Typen können keine exponentiellen Zahlen
lesen; @code{Field_decimal::store(const char *from,uint len)} muss neu
kodiert werden, um das zu beheben.
@item
@code{mysql.cc} überarbeiten, damit weniger @code{malloc()}-Aufrufe
durchgeführt werden, wenn Feldnamen gehasht werden.
@item
Funktionen:
ADD_TO_SET(wert,set) und REMOVE_FROM_SET(wert,set)
@item
Benutzung von @code{t1 JOIN t2 ON ...} und @code{t1 JOIN t2 USING ...}
hinzufügen. Momentan kann man diese Syntax nur mit @code{LEFT JOIN}
benutzen.
@item
Volle Unterstützung für @code{unsigned long long}-Typen hinzufügen.
@item
Viele weitere Variablen für @code{show status}. Zähler für:
@code{INSERT}-/@code{DELETE}-/@code{UPDATE}-Statements. Gelesene und
aktualisierte Datensätze. Select auf 1 Tabelle und Selects mit Joins.
Durchschnittliche Anzahl von Tabellen in Selects. Anzahl von @code{ORDER
BY}- und @code{GROUP BY}-Anfragen.
@item
Wenn man @code{mysql} mitten in einer Anfrage abbricht, sollte man eine
neue Verbindung herstellen und die alte, laufende Anfrage killen.
Alternativ könnte man den Versuch unternehmen, so etwas im Server zu
entdecken.
@item
Eine Handler-Schnittstelle für Tabelleninformation hinzufügen, damit man
sie als Systemtabelle benutzen kann. Das wäre ein bisschen langsam, wenn
man Informationen über alle Tabellen abfragt, aber sehr flexibel.
@code{SHOW INFO FROM tabelle} für Basisinformationen über Tabellen sollte
implementiert werden.
@item
Unterstützung für UNICODE hinzufügen.
@item
@code{NATURAL JOIN} und @code{UNION JOIN}.
@item
Anfragen wie @code{select a from crash_me left join crash_me2 using (a)}
zulassen; in diesem Fall wird angenommen, dass a aus der crash_me-Tabelle
kommt.
@item
Überarbeitung, damit @code{ON} und @code{USING} mit dem
@code{JOIN}-Verknüpfungstyp funktioniert.
@item
Oracle-mäßiges @code{CONNECT BY PRIOR ...}, um hierarchische Strukturen zu
durchsuchen.


@item
@code{mysqladmin copy datenbank neue_datenbank}. -- Erfordert, dass
@code{mysqld} der COPY-Befehl hinzugefügt wird.
@item
Prozessliste sollte die Anzahl von Anfragen pro Thread zeigen.
@item


@code{SHOW HOSTS} zur Informationsausgaben über den Hostnamen-Cache.
@item



@item
Format von @code{DATETIME} ändern, um Bruchteile von Sekunden zu speichern.
@item
Alle fehlenden ANSI92- und ODBC 3.0-Typen hinzufügen.
@item
Für berechnete Spalten Tabellennamen von leerer Zeichenkette zu @code{NULL}
ändern.
@item
'Item_copy_string' nicht auf numerische Werte anwenden, um
Zahl->Zeichenkette->Zahl-Umwandlung zu vermeiden, im Falle von:
@code{SELECT COUNT(*)*(id+0) FROM tabelle GROUP BY id}
@item
Benutzung der neuen GNU-regexp-Bibliothek anstelle der aktuellen
ermöglichen (die GNU-Bibliothek sollte viel schneller sein als die alte).
@item
@code{ALTER TABLE} sollte nicht mehr Clients abbrechen, die @code{INSERT
DELAYED} ausführen.
@item
So überarbeiten, dass, wenn Spalten, auf die in einer @code{UPDATE}-Klausel
verwiesen wird, die alten Werte enthalten, bevor das Update begonnen wird.
@item
@code{myisamchk}, @code{REPAIR} und @code{OPTIMIZE TABLE} sollten in der
Lage sein, mit Fällen umzugehen, wo die Daten und / oder Indexdateien
symbolische Links sind.
@item
Simulation von @code{pread()}/@code{pwrite()} auf Windows einarbeiten, um
konkurrierende Inserts zu ermöglichen.
@item
Ein Logdatei-Analyzer, aus dem Informationen herausgefiltert (geparst)
werden können, welche Tabellen am häufigsten angesprochen werden, wie oft
Verknüpfungen (Joins) mit mehreren Tabellen ausgeführt werden usw. Es
sollte Benutzern helfen, Bereiche oder Dinge im Tabellenentwurf zu
erkennen, die optimiert werden können, um sehr viel effizientere Anfragen
auszuführen.
@item
Add @code{SUM(DISTINCT)}
@item
@code{ANY()}-,@code{EVERY()}- und @code{SOME()}-Gruppierungsfunktionen
hinzufügen. In ANSI-SQL funktionieren diese auf boolsche Spalten, aber wir
können sie so erweitern, dass sie mit beliebigen Spalten / Ausdrücken
funktionieren, indem wir folgendes anwenden: wert == 0 -> FALSE und
wert <> 0 -> TRUE.
@item
So überarbeiten, dass @code{MAX(column)} vom selben Typ ist wie der
Spaltentyp.
@example
create tabelle t1 (a DATE);
insert into t1 values (now());
create tabelle t2 select max(a) von t1;
show columns from t2;
@end example
@item
Eine nette Syntax für ein Statement entwickeln, dass auf eine Zeile ein
@code{UPDATE} ausführt, wenn sie existiert, und eine neue Zeile einfügt
(@code{INSERT}), wenn sie nicht existiert (so wie @code{REPLACE} bei
@code{INSERT} / @code{DELETE} funktioniert).
@end itemize


@node TODO sometime, TODO unplanned, TODO future, TODO
@c German node TODO irgendwann
@subsection Dinge die irgendwann gemacht werden müssen

@itemize @bullet
@item
Funktion implementieren: @code{get_changed_tables(timeout,table1,table2,...)}
@item
Lesen durch Tabellen so ändern, das memmap benutzt wird, falls möglich.
Momentan benutzen nur komprimierte Tabellen memmap.
@item
Ein neues Zugriffsrecht @strong{'Show_priv'} für @code{SHOW}-Befehle
hinzufügen.
@item
Den automatischen Zeitstempel-Code netter machen. Zeitstempel zum
Update-Log hinzufügen mit @code{SET TIMESTAMP=#;}
@item
An manchen Stellen read/write mutex benutzen, um mehr Geschwindigkeit zu
erhalten.
@item
Volle Unterstützung von Fremdschlüsseln. Wahrscheinlich wird man zuerst
einmal eine prozedurale Sprache implementieren wollen.
@item
Einfache Sichten (Views; zunächst auf eine Tabelle, später auf jeden
beliebigen Ausdruck).
@item
Automatisches Schließen einiger Tabellen, wenn eine Tabelle, eine
temporäre Tabelle oder eine temporäre Datei einen Fehler 23 bekommt
(nicht genug offene Dateien).
@item
Wenn ein Feld=# gefunden wird, alle Vorkommen von Feld auf # setzen.
Momentan wird das nur in einigen einfachen Fällen gemacht.
@item
Alle konstanten Ausdrücke mit berechneten Ausdrücken austauschen, falls
möglich.
@item
schlüssel = ausdruck optimieren. Momentan wird nur schlüssel = feld oder
schlüssel = konstante optimiert.
@item
Einige der Copy-Funktionen verbinden, um netter Code zu erhalten.
@item
@file{sql_yacc.yy} in einen Inline-Parser umändern, um die Größe zu
reduzieren und bessere Fehlermeldungen zu erhalten (5 Tage).
@item
Den Parser so ändern, dass er nur eine Regel pro unterschiedlicher Anzahl
von Argumenten in Funktionen benutzt.
@item
Die Benutzung von vollen Berechnungsnamen (full calculation names) im
ORDER-Teil (order part). (Für ACCESS97)
@item
@code{UNION}, @code{MINUS}, @code{INTERSECT} und @code{FULL OUTER JOIN}.
(Momentan wird nur @code{LEFT OUTER JOIN} unterstützt.)
@item
@code{UNIQUE} bei Feldern zulassen, die @code{NULL} sein können.
@item
@code{SQL_OPTION MAX_SELECT_TIME=#} um einer Anfrage eine Zeitbeschränkung
zu setzen.
@item
@c Question: Check translation!
Make the update log to a Datenbank.
Update soll in eine Datenbank loggen.
@item
Negative @code{LIMIT}-Parameter, um Daten vom Ende abrufen zu können.
@item
@c Question: Alarm? Wake up?
Alarm around client connect/read/write Funktionen.
@item
Bitte beachten sie die Änderungen in @code{safe_mysqld}: Nach FSSTND (woran
sich Debian versucht zu halten) sollten PID-Dateien als
@file{/var/run/<progname>.pid} angelegt werden und Log-Datei in
@file{/var/log}. Es wäre nett, wenn man "DATADIR" in die erste Deklaration
von "pidfile" und "log" packen könnte, damit die Unterbringung dieser
Dateien mit einem einzigen Statement geändert werden könnte.
@item
Einem Client erlauben, Mitloggen anzufordern.
@item
Benutzung von @code{zlib()} für @code{gzip}-te Dateien in @code{LOAD DATA
INFILE} zulassen.
@item
Sortieren und Gruppieren von @code{BLOB}-Spalten in Ordnung bringen
(teilweise bereits gelöst).
@item
Gespeicherte Prozeduren. Wird aktuell nicht als sehr wichtig erachtet, weil
gespeicherte Prozeduren noch nicht sehr standardisiert sind. Ein weiteres
Problem besteht darin, dass es echte gespeicherte Prozeduren dem Optimierer
viel schwerer machen und dass in vielen Fällen das Ergebnis langsamer sein
wird als vorher. Auf der anderen Seite werden wir versuchen, eine einfache
(atomische) Update-Sprache hinzuzufügen, die benutzt werden kann, um
Schleifen und ähnliches im MySQL-Server zu schreiben.
@item
So ändern, dass Semaphore benutzt werden, wenn Threads gezählt werden. Man
sollte zuerst eine Semaphor-Bibliothek zu MIT-pThreads implementieren.
@item
Keinen neuen @code{AUTO_INCREMENT}-Wert zuweisen, wenn eine Spalte auf 0
gesetzt wird. Statt dessen @code{NULL} setzen.
@item
Volle Unterstützung von Verknüpfungen (@code{JOIN}) mit Klammern.
@item
Als Alternative für einen Thread pro Verbindung einen Pool von Threads
verwalten, der die Anfragen handhabt.
@item
Einem gestatten, mehr als eine Sperre (Lock) mit @code{GET_LOCK} zu
erhalten. Wenn man das tut, muss man die möglichen Deadlocks handhaben, die
diese Änderung einführen wird.
@end itemize

Zeitangaben stehen für den Umfang der Arbeit, nicht für echte Zeit.


@node TODO unplanned,  , TODO sometime, TODO
@c German node TODO ungeplant
@subsection Ein paar Dinge, für deren Umsetzung wir keine Pläne haben

@itemize @bullet
@item
Nichts; auf lange Sicht planen wir, voll ANSI-92- / ANSI-99-kompatibel zu
sein.
@end itemize


@node Comparisons,  , TODO, Deutsch
@c German node Vergleiche
@section MySQL im Vergleich mit anderen Datenbanken

@cindex Datenbanken, MySQL im Vergleich mit anderen
@cindex Vergleich, MySQL zu anderen


Dieser Abschnitt vergleicht MySQL mit anderen populären Datenbanken.  

Dieser Abschnitt wurde von den MySQL-Entwicklern geschrieben. Das sollte
man beim Lesen im Hinterkopf behalten. In diesem Abschnitt sind - soweit
uns bekannt - keine sachlichen Fehler enthalten. Wenn Sie etwas finden, was
Sie als sachlichen Fehler erachten, kontaktieren Sie uns bitte unter
@email{docs@@mysql.com}.

Eine Liste aller unterstützten Limits, Funktionen und Typen finden Sie auf
der @code{crash-me}-Webseite auf
@uref{http://www.mysql.com/information/crash-me.php}.


@menu
* Compare mSQL::                
* Compare PostgreSQL::          
@end menu

@node Compare mSQL, Compare PostgreSQL, Comparisons, Comparisons
@c German node Vergleich mit mSQL
@subsection MySQL im Vergleich mit @code{mSQL}

@table @strong
@item Performance

Um einen echten Geschwindigkeitsvergleich zu sehen, schauen Sie bitte in
der wachsenden Liste der MySQL-Benchmarks nach. @xref{MySQL Benchmarks}.

Weil es keinen Overhead für die Erzeugung von Threads besitzt, einen
kleineren Parser, weniger Features und einfache Sicherheitsmechanismen,
sollte @code{mSQL} in folgenden Punkten schneller sein:

@itemize @bullet
@item
Tests, die wiederholten Verbindungsaufbau und -abbau durchführen, wobei
während jeder Verbindung eine sehr einfache Anfrage ausgeführt wird.

@item
@code{INSERT}-Operationen auf sehr einfache Tabellen mit wenigen Spalten
und Schlüsseln.

@item
@code{CREATE TABLE} und @code{DROP TABLE}.

@item
@code{SELECT} auf alles, was kein Index ist. (Ein Tabellen-Scan ist sehr
einfach.)
@end itemize

Weil diese Operationen so einfach sind, ist es schwer, hier besser zu sein,
wenn man beim Starten einen größeren Overhead hat. Nachdem die Verbindung
erst einmal aufgebaut ist, sollte MySQL wesentlich bessere Leistungsdaten
bringen.

Andererseits ist MySQL sehr viel schneller als @code{mSQL} (und den meisten
anderen SQL-Implementationen) bei Folgendem:

@itemize @bullet
@item
Komplexe @code{SELECT}-Operationen.

@item
Wenn große Ergebnismengen abgefragt werden (MySQL hat ein besseres,
schnelleres und sichereres Protokoll).

@item
Tabellen mit Zeichenketten variabler Länge, denn MySQL hat eine
effizientere Handhabung und kann Indizes auf @code{VARCHAR}-Spalten haben.

@item
Handhabung von Tabellen mit vielen Spalten.

@item
Handhabung von Tabellen mit großer Datensatzlänge.

@item
@code{SELECT} mit vielen Ausdrücken.

@item
@code{SELECT} auf große Tabellen.

@item
Handhabung vieler gleichzeitiger Verbindungen. MySQL ist voll
Multi-Thread-fähig. Jede Verbindung hat ihren eigenen Thread, was bedeutet,
dass kein Thread auf einen anderen warten muss (ausser wenn ein Thread eine
Tabelle verändert, auf die ein anderer Thread zugreifen will). In
@code{mSQL} müssen nach dem Verbindungsaufbau alle anderen warten, bis die
erste Verbindung beendet wurde, egal, ob diese Verbindung eine Anfrage
ausführt, die kurz oder lang ist. Wenn die erste Verbindung abgebaut wird,
kann die zweite bedient werden, während alle anderen noch warten, usw.

@item
Joins (Verknüpfungen).
@code{mSQL} kann krankhaft langsam werden, wenn Sie die Reihenfolge von
Tabellen in einem @code{SELECT}-Statement ändern. In einem Benchmark-Test
wurde beobachtet, dass es mehr als 15000-mal langsamer werden kann als
MySQL. Das liegt daran, dass @code{mSQL} keinen Verknüpfungs-Optimierer
(Join Optimizer) besitzt, der die Tabellen in optimale Reihenfolge bringt.
Wenn Sie allerdings exakt die richtige Reihenfolge in @code{mSQL}2 benutzen
und wenn die @code{WHERE}-Klausel einfach ist und Spalten-Indexe benutzt,
wird die Verknüpfung relativ schnell sein!
@xref{MySQL Benchmarks}.

@item
@code{ORDER BY} und @code{GROUP BY}.

@item
@code{DISTINCT}.

@item
Benutzung von @code{TEXT}- oder @code{BLOB}-Spalten.
@end itemize

@item SQL-Features

@itemize @bullet
@item @code{GROUP BY} und @code{HAVING}.
@code{mSQL} unterstützt @code{GROUP BY} überhaupt nicht.
MySQL unterstützt @code{GROUP BY} vollständig, sowohl mit @code{HAVING} als
auch mit den folgenden Funktionen: @code{COUNT()}, @code{AVG()}, @code{MIN()},
@code{MAX()}, @code{SUM()} und @code{STD()}.  @code{COUNT(*)} ist darauf
optimiert, sehr schnell Ergebnisse zu liefern, wenn @code{SELECT} aus einer
Tabelle abfragt, wenn keine andere Spalte abgerufen wird und wenn es keine
@code{WHERE}-Klausel gibt. @code{MIN()} und @code{MAX()} können
Zeichenketten-Argumente entgegennehmen.

@item @code{INSERT} und @code{UPDATE} mit Berechnungen.
MySQL kann Berechnungen in @code{INSERT}- oder @code{UPDATE}-Statements
ausführen. Beispiel:

@example
mysql> UPDATE SET x=x*10+y WHERE x<20;
@end example

@item Aliase.
MySQL hat Spalten-Aliase.

@item Qualifizierende Spaltenamen.
In MySQL muss man nicht den voll qualifizierenden Namen benutzen, wenn eine
Spalte in den benutzten Tabellen eindeutig ist.

@item @code{SELECT} mit Funktionen.
MySQL hat viele Funktionen (zu viele, um sie hier aufzulisten; siehe
@ref{Functions}).

@end itemize

@item Effiziente Ausnutzung von Speicherplatz
Das heißt, wie klein können Sie Ihre Tabellen machen?

MySQL hat sehr präzise Typen, deshalb können Sie Tabellen erzeugen, die
sehr wenig Platz brauchen. Ein Beispiel für einen nützlichen MySQL-Datentyp
ist @code{MEDIUMINT}, der 3 Bytes lang ist. Wenn Sie 100 Millionen
Datensätze haben, ist es schon von Wichtigkeit, auch nur ein Byte pro
Datensatz zu sparen.

@code{mSQL2} hat eine begrenztere Anzahl von Spaltentypen, daher ist es
schwieriger, kleine Tabellen zu erhalten.

@item Stabilität
Dieser Punkt ist schwieriger objektiv zu beurteilen. Eine Erörterung der
Stabilität von MySQL finden Sie hier: @ref{Stability}.

Wir haben keine Erfahrungen mit der Stabilität von @code{mSQL}, daher
können wir nichts darüber sagen.

@item Preis
Ein weiterer wichtiger Punkt ist die Lizenz. MySQL hat eine flexiblere
Lizenz als @code{mSQL} und kostet auch weniger als @code{mSQL}. Welches
Produkt auch immer Sie verwenden, ziehen Sie bitte zumindestens in
Betracht, für eine Lizenz oder E-Mail-Support zu zahlen. (Sie müssen
natürlich notwendigerweise eine Lizenz erwerben, wenn Sie MySQL in ein
Produkt einbeziehen, das Sie verkaufen.)

@item Perl-Schnittstellen
MySQL hat prinzipiell dieselben Schnittstelle zu Perl wie @code{mSQL}, mit
einigen zusätzlichen Features.

@item JDBC (Java)
MySQL hat aktuell eine große Anzahl von JDBC-Treibern:

@itemize @bullet
@item
Die mm-Treiber: Ein Typ-4 JDBC-Treiber von Mark Matthews
@email{mmatthew@@ecn.purdue.edu}.  Er ist unter LGPL veröffentlicht.

@item
Der Resin-Treiber. Das ist ein kommerzieller JDBC-Treiber, der unter Open
Source veröffentlicht ist. @uref{http://www.caucho.com/Projekte/jdbc-mysql/index.xtp}

@item
Der gwe-Treiber: Eine Java-Schnittstelle von GWE technologies (wird nicht
mehr unterstützt).

@item
Der jms-Treiber: Ein verbesserter gwe-Treiber von Xiaokun Kelvin ZHU
@email{X.Zhu@@brad.ac.uk} (wird nicht mehr unterstützt).

@item
Der twz-Treiber: Ein Typ-4 JDBC-Treiber von Terrence W. Zellers
@email{zellert@@voicenet.com}.  Das ist ein kommerzieller Treiber, der für
Privatgebrauch und Schulungszwecke kostenlos ist (wird nicht mehr
unterstützt).
@end itemize

Der empfohlene Treiber ist der mm-Treiber. Der Resin-Treiber mag auch gut
sein (zumindest sehen die Benchmarks gut aus), aber wir haben über diesen
Treiber noch nicht allzu viele Informationen erhalten.

Wir wissen, dass @code{mSQL} einen JDBC-Treiber hat, aber wir haben zu
wenig Erfahrung damit, um ihn in einen Vergleich einzubeziehen.

@item Entwicklungsgeschwindigkeit
MySQL hat ein sehr kleines Entwicklerteam, aber wir arbeiten schon lange
mit C und C++ und sind daher sehr schnell. Weil Threads, Funktionen,
@code{GROUP BY} usw. noch nicht in @code{mSQL} implementiert sind, hat es
eine Menge aufzuholen. Um das in den richtigen Blickwinkel zu rücken,
können Sie sich die @code{mSQL} @file{HISTORY}-Datei des letzten Jahres
ansehen und sie mit dem News-Abschnitt des MySQL Referenzhandbuchs
vergleichen (@pxref{News}). Es ist ziemlich offensichtlich, welches System
sich schneller entwickelt hat.

@item Utilities
Sowohl @code{mSQL} als auch MySQL haben viele interessante von Dritten
entwickelte Werkzeuge. Weil es sehr einfach ist, aufwärts zu portieren (von
@code{mSQL} zu MySQL), sind fast alle interessanten Applikationen, die für
@code{mSQL} verfügbar sind, auch für MySQL erhältlich.

MySQL liefert ein einfaches @code{msql2mysql}-Programm mit, das
Unterschiede in der Schreibweise zwischen @code{mSQL} und MySQL für die
meistbenutzten C-API-Funktionen bereinigt.
Es ändert zum Beispiel Instanzen von @code{msqlConnect()} zu
@code{mysql_connect()}. Ein Client-Programm von @code{mSQL} zu MySQL zu
konvertieren, erfordert meist nur geringe Anstrengung.
@end table



@menu
* Using mSQL tools::            
* Protocol differences::        
* Syntax differences::          
@end menu

@node Using mSQL tools, Protocol differences, Compare mSQL, Compare mSQL
@c German node mSQL-Werkzeuge benutzen
@subsubsection Wie man @code{mSQL}-Werkzeuge für MySQL konvertiert

@cindex MySQL-Werkzeuge, Konvertierung
@cindex Konvertierung, Werkzeuge
@cindex Werkzeuge, Konvertierung

Nach unserer Erfahrung nimmt es wenig Zeit in Anspruch, Werkzeuge wie
@code{msql-tcl} und @code{msqljava} zu konvertieren, die die
@code{mSQL}-C-API benutzen, damit sie mit der MySQL-C-API funktionieren.

Die Konvertierungsprozedur läuft wie folgt:

@enumerate
@item
Lassen Sie das Shell-Skript @code{msql2mysql} über den Quelltext laufen.
Das erfordert das @code{replace}-Programm, das mit MySQL ausgeliefert wird.

@item
Kompilieren.

@item
Alle Kompilierfehler beheben.
@end enumerate

Die Unterschiede zwischen der @code{mSQL}-C-API und der MySQL-C-API sind:

@itemize @bullet
@item
MySQL benutzt eine @code{MYSQL}-Struktur als Verbindungstyp, (@code{mSQL}
benutzt einen @code{int}).

@item
@code{mysql_connect()} nimmt einen Zeiger (Pointer) auf eine
@code{MYSQL}-Struktur als Parameter auf. Es ist einfach, einen global zu
definieren oder @code{malloc()} zu benutzen, um einen zu erhalten.
@code{mysql_connect()} nimmt zusätzlich zwei Parameter auf, um Benutzer und
Passwort zu spezifizieren. Sie können diese als Vorgabewert der Benutzung
auf @code{NULL, NULL} setzen.

@item
@code{mysql_error()} nimmt die @code{MYSQL}-Struktur als Parameter auf.
Fügen Sie einfach den Parameter zu Ihrem alten @code{msql_error()}-Code
hinzu, wenn Sie alten Code portieren.

@item
MySQL gibt eine Fehlernummer und eine Textnachricht für alle Fehler zurück.
@code{mSQL} gibt nur eine Fehlernachricht zurück.

@item
Aufgrund der Tatsache, dass MySQL mehrfache Verbindungen zum Server von
demselben Prozess aus unterstützt, existieren einige Inkompatibilitäten.
@end itemize


@node Protocol differences, Syntax differences, Using mSQL tools, Compare mSQL
@c German node Protokollunterschiede
@subsubsection Wie sich @code{mSQL}- und MySQL-Client/Server-Kommunikationsprotokolle unterscheiden

@cindex Kommunikationsprotokolle
@cindex mSQL, im Vergleich zu MySQL

Es gibt genug Unterschiede, so dass es unmöglich ist (oder zumindest nicht
leicht), beide zu unterstützen.

Die signifikantesten Protokollunterschiede zwischen MySQL und @code{mSQL}
sind folgende:

@itemize @bullet
@item
Ein Nachrichtenpuffer (Message Buffer) darf viele Ergebniszeilen enthalten.

@item
Die Nachrichtenpuffer werden dynamisch vergrößert, wenn die Anfrage oder
das Ergebnis größer sind als der aktuelle Puffer, bis hin zu einer
konfigurierbaren Server- und Client-Grenze.

@item
Alle Pakete werden nummeriert, um duplizierte oder fehlende Pakete
abzufangen.

@item
Alle Spaltenwerte werden in ASCII gesendet. Die Längen von Spalten und
Zeilen werden als komprimierte Binärkodierung gesendet (1, 2 oder 3
Bytes).

@item
MySQL kann ungepuffert im Ergebnis lesen (ohne die volle Ergebnismenge im
Client speichern zu müssen).

@item
Wenn ein einzelner Lese- / Schreibvorgang mehr als 30 Sekunden in Anspruch
nimmt, schließt der Server die Verbindung.

@item
Wenn eine Verbindung länger als 8 Stunden im Leerlauf ist, schließt der
Server die Verbindung.
@end itemize


@c Question Steve: Check this node for the English original!
@node Syntax differences,  , Protocol differences, Compare mSQL
@c German node Syntaxunterschiede
@subsubsection Wie sich die @code{mSQL} 2.0 SQL-Syntax von MySQL unterscheidet

@noindent
@strong{Spaltentypen}

@table @code
@item
MySQL hat folgende zusätzliche Typen (unter anderem;
@pxref{CREATE TABLE, , @code{CREATE TABLE}}):
@itemize @bullet
@item
@code{ENUM}-Typ für einen Satz von Zeichenketten.
@item
@code{SET}-Typ für viele Sätze von Zeichenketten.
@item
@code{BIGINT}-Typ für 64-Bit-Ganzzahlen (Integer).
@end itemize
@item
MySQL unterstützt folgende zusätzliche Typ-Attribute:
@itemize @bullet
@item
@code{UNSIGNED}-Option für Ganzzahl-Spalten (Integer).
@item
@code{ZEROFILL}-Option für Ganzzahl-Spalten (Integer).
@item
@code{AUTO_INCREMENT}-Option für Ganzzahl-Spalten (Integer), die ein
@code{PRIMARY KEY} sind.
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
@item
@code{DEFAULT}-Wert für alle Spalten.
@end itemize
@item mSQL2
@code{mSQL}-Spaltentypen korrespondieren mit den unten dargestellten
MySQL-Typen:
@multitable @columnfractions .15 .85
@item @code{mSQL} @strong{Typ} @tab @strong{Korrespondierender MySQL-Typ}
@item @code{CHAR(len)} @tab @code{CHAR(len)}
@item @code{TEXT(len)} @tab @code{TEXT(len)}. @code{len} ist die maximale
Länge.
Und @code{LIKE} funktioniert.
@item @code{INT} @tab @code{INT}. Mit vielen weiteren Optionen!
@item @code{REAL} @tab @code{REAL}. Or @code{FLOAT}. Beide 4- und
8-Byte-Versionen sind verfügbar.
@item @code{UINT} @tab @code{INT UNSIGNED}
@item @code{DATE} @tab @code{DATE}. Benutzt ANSI-SQL-Format statt 
@code{mSQL}'s eigenem Format.
@item @code{TIME} @tab @code{TIME}
@item @code{MONEY} @tab @code{DECIMAL(12,2)}. Ein Festkomma-Wert mit zwei
Dezimalstellen.
@end multitable
@end table

@noindent
@strong{Index-Erzeugung}

@table @code
@item MySQL
Indizes können bei der Erzeugung der Tabelle mit dem @code{CREATE
TABLE}-Statement festgelegt werden.
@item mSQL
Indexe müssen erzeugt werden, nachdem die Tabelle erzeugt wurde, mit einem
separaten @code{CREATE INDEX}-Statements.
@end table

@noindent
@strong{Einfügen eines eindeutigen Identifikators (Unique Identifier) in eine Tabelle}

@table @code
@item MySQL
Benutzen Sie @code{AUTO_INCREMENT} als Spaltentyp-Spezifizierer.
@xref{mysql_insert_id, , @code{mysql_insert_id()}}.
@item mSQL
Erzeugen Sie eine @code{SEQUENCE} auf eine Tabelle und wählen Sie die
@code{_seq}-Spalte.
@end table

@noindent
@strong{Wie man einen eindeutigen Identifikator (Unique Identifier) für eine Zeile erhält}

@table @code
@item MySQL
Fügen Sie der Tabelle einen @code{PRIMARY KEY} oder @code{UNIQUE}-Schlüssel
hinzu und benutzen Sie diesen.
Neu ab Version 3.23.11: Wenn der @code{PRIMARY}- oder
@code{UNIQUE}-Schlüssel nur aus einer Spalte besteht und diese vom Typ
Ganzzahl (Integer) ist, können Sie auf diese auch mit @code{_rowid}
verweisen.
@item mSQL
Benutzen Sie die @code{_rowid}-Spalte. Beachten Sie, dass sich
@code{_rowid} im Zeitverlauf möglicherweise ändert, abhängig von vielen
Faktoren.
@end table

@noindent
@strong{Wie man die Zeit erhält, zu der eine Spalte zuletzt geändert wurde}

@table @code
@item MySQL
Fügen Sie der Tabelle eine @code{TIMESTAMP}-Spalte hinzu. Diese Spalte wird
automatisch auf das aktuelle Datum und die aktuelle Zeit gesetzt, und zwar
bei @code{INSERT}- und @code{UPDATE}-Statements, es sein denn, der Spalte
wird explizit ein Wert zugewiesen, auch der @code{NULL}-Wert.

@item mSQL
Benutzen Sie die @code{_timestamp}-Spalte .
@end table

@noindent
@strong{@code{NULL}-Wert-Vergleiche}

@table @code
@item MySQL
MySQL folgt ANSI-SQL, daher wird ein Vergleich mit @code{NULL} immer zu
@code{NULL} ausgewertet.
@item mSQL
In @code{mSQL} ist @code{NULL = NULL} TRUE. Sie müssen @code{=NULL} zu
@code{IS NULL} und @code{<>NULL} zu @code{IS NOT NULL}, wenn Sie alten Code
von @code{mSQL} zu MySQL portieren.
@end table

@noindent
@strong{Zeichenketten-Vergleich}

@table @code
@item MySQL
Normalerweise werden Zeichenketten-Vergleiche so durchgeführt, dass sie
unabhängig von der verwendeten Groß-/Kleinschreibung laufen, wobei die
Sortierreihenfolge vom aktuell verwendeten Zeichensatz abhängt (ISO-8859-1
Latin1 als Vorgabewert). Wenn Sie das nicht wollen, deklarieren Sie Ihre
Spalten mit dem @code{BINARY}-Attribut, was bewirkt, dass Vergleiche nach
der ASCII-Reihenfolge durchgeführt werden, wobei der ASCII-Zeichensatz
gilt, den der MySQL-Server-Host verwendet.
@item mSQL
Alle Zeichenketten-Vergleiche werden so durchgeführt, dass sie abhängig von
der verwendeten Groß-/Kleinschreibung laufen. Die Sortierung erfolgt in
ASCII-Reihenfolge.
@end table

@noindent
@strong{Suche, die unabhängig von Groß-/Kleinschreibung läuft}

@table @code
@item MySQL
@code{LIKE} ist ein Operator, der abhängig oder unabhängig von der
Groß-/Kleinschreibung läuft, was davon abhängt, welche Spalten verwendet
werden. Wenn möglich, benutzt MySQL Indexe, wenn das @code{LIKE}-Argument
nicht mit einem Platzhalterzeichen (Wildcard) beginnt.
@item mSQL
Benutzt @code{CLIKE}.
@end table

@noindent
@strong{Handhabung von Leerzeichen am Ende}

@table @code
@item MySQL
Entfernt alle Leerzeichen am Ende von @code{CHAR}- und
@code{VARCHAR}-Spalten. Benutzen Sie eine @code{TEXT}-Spalte, wenn dieses
Verhalten unerwünscht ist.
@item mSQL
Behält Leerzeichen am Ende bei.
@end table

@noindent
@strong{@code{WHERE}-Klauseln}

@table @code
@item MySQL
MySQL priorisiert alles korrekt (@code{AND} wird vor @code{OR}
ausgewertet). Um @code{mSQL}-Verhalten in MySQL zu erreichen, benutzen
Sie Klammern (wie im unten stehenden Beispiel gezeigt).
@item mSQL
Wertet alles von links nach rechts aus. Das bedeutet, dass einige logische
Berechnungen mit mehr als drei Argumenten überhaupt nicht ausgedrückt
werden können. Das heißt auch, dass Sie einige Anfragen ändern müssen,
wenn Sie auf MySQL umsteigen. Das einfachste ist, Klammern hinzuzufügen.
Nehmen wir an, Sie haben die folgende @code{mSQL}-Anfrage:
@example
mysql> SELECT * FROM tabelle WHERE a=1 AND b=2 OR a=3 AND b=4;
@end example
Damit MySQL dies auf dieselbe Art auswertet wie @code{mSQL}, müssen Sie
Klammern hinzufügen:
@example
mysql> SELECT * FROM tabelle WHERE (a=1 AND (b=2 OR (a=3 AND (b=4))));
@end example
@end table

@noindent
@strong{Zugriffskontrolle}

@table @code
@item MySQL
Hat Tabellen, in denen Berechtigungsoptionen pro Benutzer, Host, und
Datenbank gespeichert werden. @xref{Privileges}.
@item mSQL
Hat eine Datei @file{mSQL.acl}, in der Sie Lese-/Schreibrechte für Benutzer
gewähren können.
@item
@end table


@node Compare PostgreSQL,  , Compare mSQL, Comparisons
@c German node Vergleich mit PostgreSQL
@subsection MySQL im Vergleich mit PostgreSQL

@cindex PostgreSQL im Vergleich mit MySQL, Überblick

Wenn Sie das Folgende lesen, beachten Sie bitte, dass sich beide Produkte
stetig entwickeln. Wir bei MySQL AB und die PostgreSQL-Entwickler geben
sich alle Mühe, unsere jeweilige Datenbank so gut wie möglich zu machen.
Daher sind es beide Produkte wert bei der Wahl einer kommerziellen Datenbank
ernsthaft in Betracht gezogen zu werden.

Der folgende Vergleich wurde von uns bei MySQL AB durchgeführt. Wir haben
uns bemüht, so akkurat und fair wie möglich zu sein. Da wir aber keine
vollständige Kenntnis aller PostgreSQL-Features haben, während wir MySQL
sehr genau kennen, haben wir vielleicht ein paar Dinge falsch verstanden.
Wir werden das jedenfalls korrigieren, wenn es uns zu Ohren kommt.

Zunächst wollen wir feststellen, dass sowohl PostgreSQL als auch MySQL weit
verbreitete Produkte sind, die aber unterschiedliche Entwurfsziele haben,
auch wenn beide sich bemühen, ANSI-SQL-kompatibel zu sein. Das bedeutet,
dass MySQL für einige Applikationen besser geeignet ist, PostgreSQL für
andere. Wenn Sie überlegen, welche Datenbank Sie wählen sollen, sollten Sie
zunächst prüfen, ob die Features der Datenbank für Ihre Applikation
zufrieden stellend sind. Wenn Sie satte Geschwindigkeit brauchen, wird Ihre
Wahl wahrscheinlich auf MySQL fallen. Wenn Sie einige der speziellen
Merkmale brauchen, die nur PostgreSQL anbieten kann, sollten Sie
@code{PostgreSQL} benutzen.

@cindex PostgreSQL/MySQL, Strategien


@menu
* MySQL-PostgreSQL goals::      
* MySQL-PostgreSQL features::   
* MySQL-PostgreSQL benchmarks::  
@end menu

@node MySQL-PostgreSQL goals, MySQL-PostgreSQL features, Compare PostgreSQL, Compare PostgreSQL
@c German node MySQL-PostgreSQL-Ziele
@subsubsection Entwicklungsstragien von MySQL und PostgreSQL

Wenn wir MySQL Dinge hinzufügen, ist es für uns eine Sache der Ehre, eine
optimale, definitive Lösungen zu schaffen. Der Code sollte so gut sein,
dass wir keine Notwendigkeit erkennen, ihn in der absehbaren Zukunft zu
ändern. Wir wollen auch nicht Geschwindigkeit für Features opfern, sondern
sind aufs Äußerste bestrebt, eine Lösung zu finden, die maximalen
Durchsatz bietet. Das bedeutet, dass die Entwicklung ein bisschen länger
dauert, aber die Endergebnisse sind es wert. Diese Art von Entwicklung ist
nur möglich, weil der gesamte Server-Code nur von wenigen Leuten geprüft
wird (aktuell zwei), bevor er in den MySQL-Server aufgenommen wird.

Wir bei MySQL AB halten viel von häufigen Releases, um in der Lage zu sein,
neue Features schnell an unsere Benutzer heraus zu geben. Deshalb bringen
wir etwa alle drei Wochen ein kleines Release heraus und einen größeren
Zweig (Branch) einmal im Jahr. Alle Releases werden gründlich mit unseren
Testwerkzeugen auf vielen verschiedenen Plattformen getestet.

PostgreSQL basiert auf einem Kern (Kernel), zu dem viele Leute etwas
beigesteuert haben. Bei diesem Vorgehen ist es sinnvoll, dem Hinzufügen
neuer Features Priorität einzuräumen, statt sie optimal zu implementieren,
denn man kann immer noch später Dinge optimieren, wenn sich die
Notwendigkeit hierfür ergibt.

Ein weiterer großer Unterschied zwischen MySQL und PostgreSQL besteht
darin, dass praktisch der gesamte Code des MySQL-Servers von Entwicklern
kodiert wurde, die bei MySQL AB angestellt sind und die immer noch am
Server-Code arbeiten. Ausnahmen bilden die Transaktions-Engines und die
Regexp-Bibliothek.

Das steht in scharfem Kontrast zum PostgreSQL-Code, wo der größte Teil des
Codes von einer großen Gruppe von Leuten mit unterschiedlichem Hintergrund
kodiert wird. Erst kürzlich gaben die PostgreSQL-Entwickler bekannt, dass
ihre aktuelle Entwicklergruppe endlich Zeit gefunden hat, einen Blick auf
all den Code der aktuellen PostgreSQL-Version zu werfen.

Beide der genannten Entwicklungsmethoden hat Ihre Vorzüge und Nachteile.
Wir hier bei MySQL AB sind natürlich der Meinung, dass unser Modell besser
ist, weil unser Modell bessere Konsistenz gewährleistet sowie mehr
optimalen und damit wiederverwendbaren Code und deshalb nach unserer
Meinung weniger Bugs. Weil wir die Autoren des MySQL-Server-Codes sind,
sind wir besser im Stande, neue Features und Releases zu koordinieren.


@node MySQL-PostgreSQL features, MySQL-PostgreSQL benchmarks, MySQL-PostgreSQL goals, Compare PostgreSQL
@c German node MySQL-PostgreSQL-Features
@subsubsection Feature-Vergleich von MySQL und PostgreSQL

@cindex PostgreSQL/MySQL, Features

Auf der Seite @uref{http://www.mysql.com/information/crash-me.php,
crash-me} finden Sie eine Liste der Datenbank-Konstrukte und
-Beschränkungen, die man automatisch mit einem Programm entdecken kann.
Beachten Sie jedoch, dass sich etliche numerische Beschränkungen mit
Start-Optionen der jeweiligen Datenbank ändern lassen. Die genannte Seite
ist jedoch äußerst nützlich, wenn Sie sicher stellen wollen, dass Ihre
Applikationen mit vielen unterschiedlichen Datenbanken funktionieren, oder
wenn Sie Ihre Applikation von einer Datenbank zu einer anderen konvertieren
wollen.

MySQL bietet folgende Vorzüge gegenüber PostgreSQL:

@itemize @bullet
@item
@code{MySQL} ist generell viel schneller als PostgreSQL.
@xref{MySQL-PostgreSQL benchmarks}.

@item
MySQL hat eine viel größere Benutzer-Basis als PostgreSQL, deshalb ist der
Code besser getestet und hat sich historisch als stabiler erwiesen als der
von PostgreSQL.  MySQL wird sehr viel mehr in Produktionsumgebungen
eingesetzt als PostgreSQL, hauptsächlich dank der Tatsache, dass MySQL AB,
früher TCX DataKonsult AB, kommerziellen Support von höchster Qualität für
MySQL geleistet hat, von dem Tag an, wo MySQL veröffentlicht wurde,
wohingegen PostgreSQL bis vor kurzem nicht supported war.

@item
MySQL funktioniert unter Windows besser als PostgreSQL.  MySQL läuft als
native Windows-Applikation (als Systemdienst unter NT/Win2000/WinXP),
während PostgreSQL unter der cygwin-Emulation läuft. Uns ist zu Ohren
gekommen, dass PostgreSQL nicht unter Windows nicht sehr stabil läuft, aber
wir konnten das selbst noch nicht überprüfen.

@item
MySQL hat mehr APIs zu anderen Sprachen und wird von mehr existierenden
Programmen unterstützt als PostgreSQL.  @xref{Contrib}.

@item
MySQL läuft auf 24/7-Systemen unter hoher Last. In den meisten Fällen
braucht man nie irgend welche Cleanups auf MySQL laufen lassen. PostgreSQL
unterstützt noch keine 24/7-Systeme, weil man gelegentlich @code{VACUUM()}
laufen lassen muss, um durch @code{UPDATE}- und @code{DELETE}-Kommandos
beanspruchten Platz zurück zu gewinnen, sowie um statistische Analysen
durchzuführen, die entscheidend sind, um mit PostgreSQL gute Performance zu
erzielen. @code{VACUUM()} wird auch benötigt nach dem Hinzufügen vieler
Zeilen in eine Tabelle. Auf einem ausgelasteten System mit vielen
Änderungen muss @code{VACUUM()} sehr häufig laufen gelassen werden, im
schlimmsten Fall mehrmals täglich. Während @code{VACUUM()} läuft, was
Stunden dauern kann, wenn die Datenbank Groß ist, ist die Datenbank vom
Produktionsstandpunkt her gesehen praktisch tot. Das PostgreSQL-Team hat
die Behebung dessen auf seiner TODO-Liste, aber wir vermuten, dass es nicht
einfach sein wird, das dauerhaft zu beheben.

@item
Ein funktionierendes, getestetes Replikations-Feature, das unter anderem
von folgenden Sites benutzt wird:
@itemize @minus
@item Yahoo Finance (@uref{http://finance.yahoo.com})
@item Mobile.de (@uref{http://www.mobile.de/})
@item Slashdot (@uref{http://www.slashdot.org})
@end itemize

@item
In der MySQL-Distribution werden zwei unterschiedliche Test-Suites
mitgeliefert:
@file{mysql-test-run} und 
@uref{http://www.mysql.com/information/crash-me.php,crash-me}, sowie eine
Benchmark-Suite. Das Testsystem wird rege mit Code aktualisiert, um jedes
neue Feature und alle wiederholbaren Fehler, die uns zu Ohren kamen, zu
testen. Vor jedem Release testen wir MySQL auf vielen verschiedenen
Plattformen. Diese Tests sind technisch ausgereifter als alles, was wir von
PostgreSQL gesehen haben, und sie stellen sicher, dass MySQL auf einem
hohen Standard gehalten wird.

@item
Es gibt wesentlich mehr gedruckte Bücher über MySQL als über PostgreSQL.
Alle großen Verlage wie O'Reilly, Sams, Que und New Riders bieten Bücher
über MySQL an. Alle MySQL-Features werden ausserdem im
MySQL-Online-Handbuch dokumentiert, denn wenn ein neues Feature
implementiert wird, sind die MySQL-Entwickler gehalten, es zu
dokumentieren, bevor es in den Quelltext eingeschlossen wird.

@item
MySQL unterstützt mehr Standard-ODBC-Funktionen als @code{PostgreSQL}.

@item
MySQL hat ein technisch ausgereifteres @code{ALTER TABLE}.

@item
MySQL unterstützt Tabellen ohne Transaktionen für Applikationen, die so
viel Geschwindigkeit brauchen, wie sie bekommen können. Tabellen können
Arbeitsspeicher-basierend, @code{HEAP}-Tabellen oder Festplatten-basierend
@code{MyISAM} sein. @xref{Table types}.

@item
MySQL unterstützt zwei verschiedene Tabellen-Handler, die Transaktionen
unterstützen: @code{BerkeleyDB} und @code{InnoDB}. Weil jede
Transaktions-Engine unter unterschiedlichen Bedingungen unterschiedlich
leistungsfähig ist, gibt das dem Applikationsschreiber mehr Optionen, die
optimale Lösung für seinen Bedarf zu finden. @xref{Table types}.

@item
@code{MERGE}-Tabellen geben Ihnen eine einzigartige Möglichkeit, eine
augenblickliche Sicht (View) über eine Reihe identischer Tabellen zu machen
und diese wie eine zu benutzen. Das ist perfekt für Systeme, auf denen Sie
Log-Dateien haben, die Sie zum Beispiel nach Monat sortieren. @xref{MERGE}.

@item
Die Option, Nur-Lese-Tabellen zu komprimieren, aber dennoch direkten
Zugriff auf die Zeilen der Tabelle zu haben, gibt Ihnen dadurch bessere
Performance, dass Festplattenzugriffe minimiert werden. Das ist sehr
nützlich, wenn Sie Dinge archivieren. @xref{myisampack}.

@item
MySQL hat internen Support für Volltextsuche. @xref{Fulltext Search}.

@item
Sie können von derselben Verbindung aus auf viele Datenbanken zugreifen
(was natürlich von Ihren Zugriffsrechten abhängt).

@item
MySQL wurde von Anfang an multi-threaded kodiert, während PostgreSQL
Prozesse benutzt. Umschalten zwischen unterschiedlichen Zusammenhängen
(Context Switching) und Zugriff auf allgemeine Speicherbereiche geht
zwischen Threads wesentlich schneller als zwischen separaten Prozessen. Das
bringt MySQL einen großen Geschwindigkeitsvorteil in
Mehrbenutzer-Applikationen und macht es obendrein für MySQL einfacher, den
vollen Nutzen aus symmetrischen Multiprozessor-Systemen (SMP) zu ziehen.

@item
MySQL hat ein technisch ausgereifteres System der Zugriffsberechtigungen
(Berechtigungssystem) als PostgreSQL.  
PostgreSQL unterstützt nur @code{INSERT}-, @code{SELECT}- und
@code{UPDATE/DELETE}-Rechtegewährung (Grants) pro Benutzer auf eine
Datenbank oder Tabelle. MySQL dagegen erlaubt es Ihnen, einen kompletten
Satz unterschiedlicher Zugriffsrechte auf Datenbank-, Tabellen- und 
Spaltenebene festzulegen.  MySQL gestattet es auch, Zugriffsrechte als
Host- und Benutzer-Kombinationen festzulegen. @xref{GRANT}.

@item
MySQL unterstützt ein komprimiertes Client/Server-Protokoll, was die
Performance über langsame Verbindungen verbessert.

@item
MySQL führt ein ``Tabellen-Handler''-Konzept ein und ist die einzige
relationale Datenbank, die wir kennen, die um dieses Konzept herum
aufgebaut ist. Das sorgt dafür, dass unterschiedliche
Low-Level-Tabellentypen an die SQL-Engine angeflanscht werden können, und
dass jeder Tabellentyp für unterschiedliche Performance-Charakteristiken
optimiert werden kann.

@item
Alle MySQL-Tabellentypen (ausser @strong{InnoDB}) sind als Dateien
implementiert (eine Tabelle pro Datei), wodurch Datensicherungen,
Verschieben, Löschen und sogar Symlinks auf Datenbanken und Tabellen
wirklich einfach werden, selbst wenn der Server herunter gefahren ist.

@item
Werkzeuge, um @strong{MyISAM}-Tabellen (der meistbenutzte MySQL-Tabellentyp) zu
reparieren und zu optimieren. Ein Reparaturwerkzeug wird nur dann benötigt,
wenn eine Datendatei physikalisch beschädigt wurde, was üblicherweise bei
Hardwareproblemen der Fall ist. Das Werkzeug kann meist den größten Teil der
Daten retten.

@item
Auf eine höhere Version von MySQL aktualisieren (Upgrade) geht problemlos.
Wenn Sie MySQL aktualisieren, brauchen Sie Ihre Daten nicht zusichern (dump)
und zurückzusichern (restore), wie Sie es mit PostgreSQL tun müssen, wenn Sie
dieses aktualisieren.
@end itemize

Nachteile von MySQL im Vergleich zu PostgreSQL:

@itemize @bullet
@item
Die Transaktionsunterstützung in MySQL ist noch nicht so gut getestet wie
das System von PostgreSQL.

@item

Weil MySQL Threads benutzt, die auf vielen Betriebssystemen noch nicht ganz
tadellos funktionieren, muss man entweder die Binärdateien von
@uref{http://www.mysql.com/downloads} benutzen oder genau unsere
Anweisungen auf @uref{http://www.mysql.com/doc/I/n/installation_source.html}
befolgen, um eine optimale Binärdatei zu erhalten, die in jedem Fall
funktioniert.

@item
Tabellensperren (Locks), die von den nicht transaktionalen
@code{MyISAM}-Tabellen benutzt werden, sind in vielen Fällen schneller als
Seiten-Sperren (Page Locks), Zeilen-Sperren (Row Locks) oder Versionierung
(Versioning). Der Nachteil liegt jedoch darin, dass, wenn man nicht
berücksichtigt, wie Tabellensperren funktioniert, eine einzige lang
laufende Anfrage eine Tabelle lange Zeit für Updates blockieren kann. Das
kann gewöhnlich durch entsprechenden Entwurf der Applikation vermieden
werden. Falls nicht, kann man immer noch die Tabelle, die das Problem
verursacht, zu einem der transaktionalen Tabellentypen umändern.
@xref{Table locking}.

@item
Mit UDF (User Defined Functions, Benutzerdefinierten Funktionen) kann man
MySQL sowohl hinsichtlich SQL-Funktionen als auch Aggregaten erweitern,
aber das ist noch nicht so einfach und flexibel wie in PostgreSQL.
@xref{MySQL internals}.

@item
Updates, die über mehrere Tabellen laufen, sind in MySQL schwieriger
durchzuführen. Das wird jedoch in MySQL 4.0 mit dem
Multi-Table-@code{UPDATE} behoben sein und in MySQL 4.1 mit den Subselects.
In MySQL 4.0 kann man Multi-Table-Deletes nutzen, um zeitgleich in mehreren
Tabellen zu löschen. @xref{DELETE}.
@end itemize

PostgreSQL hat momentan folgende Vorteile gegenüber MySQL:

Weil wir die Pläne (Roadmap) von MySQL kennen, haben wir in der folgenden
Tabelle die Versionsnummern der jeweiligen MySQL-Version untergebracht, die
das entsprechende Feature unterstützen wird. Leider konnten wir das nicht
für frühere Vergleiche machen, denn wir kennen nicht kennen nicht die Pläne
(Roadmap) von PostgreSQL.

@multitable @columnfractions .70 .30
@item @strong{Feature}                     @tab @strong{MySQL version}
@item Subselects                           @tab 4.1
@item Fremdschlüssel                       @tab 4.0 und 4.1
@item Sichten (Views)                      @tab 4.2
@item Gespeicherte Prozeduren              @tab 4.1
@item Erweiterbares Typ-System             @tab Nicht geplant
@item Unions                               @tab 4.0
@item Full Join                            @tab 4.0 oder 4.1
@item Trigger                              @tab 4.1
@item Constrainst                          @tab 4.1
@item Cursor                               @tab 4.1 oder 4.2
@item Erweiterbare Indextypen wie R-Trees  @tab R-trees sind geplant für 4.2
@item Vererbte (Inherited) Tabellen        @tab Nicht geplant
@end multitable

Andere Gründe, PostgreSQL zu benutzen:

@itemize @bullet
@item
Im Standardgebrauch ist PostgreSQL in einigen Fällen näher an ANSI-SQL
angelehnt.

@item
Man kann PostgreSQL beschleunigen, indem man Dinge als gespeicherte
Prozeduren kodiert.

@item
PostgreSQL hat ein größeres Entwicklerteam, das Code zum Server
beisteuert.
@end itemize

Nachteile von PostgreSQL im Vergleich zu MySQL:

@itemize @bullet
@item
@code{VACUUM()} macht es problematisch, PostgreSQL in 24/7-Umgebungen
einzusetzen.

@item
Nur Transaktionstabellen.

@item
Viel langsamere @code{INSERT}, @code{DELETE} und @code{UPDATE} Anweisungen.
@end itemize

Eine vollständige Aufstellung der Nachteile finden Sie in der ersten
Tabelle dieses Abschnitts.



@node MySQL-PostgreSQL benchmarks,  , MySQL-PostgreSQL features, Compare PostgreSQL
@c German node MySQL-PostgreSQL-Benchmarks
@subsubsection Benchmark-Vergleiche von MySQL und PostgreSQL

@cindex PostgreSQL im Vergleich mit MySQL, Benchmarks

Der einzige Open-Source-Benchmark-Test, den wir kennen, der benutzt werden
kann, um MySQL und PostgreSQL (und andere Datenbanken) miteinander zu
vergleichen, ist unser eigener. Man findet ihn auf
@uref{http://www.mysql.com/information/benchmarks.html}.

Wir haben mehrfach bei den PostgreSQL-Entwicklern und bei einigen
PostgreSQL-Benutzer nachgefragt, ob sie bereit wären, uns zu helfen, diesen
Benchmark-Test zu erweitern, um ihn zu dem definitiven Benchmark-Test für
Datenbanken zu machen, haben aber leider keinerlei Rückmeldung erhalten.

Wir, die MySQL-Entwickler, haben deshalb viele Stunden damit verbracht,
für den Benchmark-Test maximale Performance aus PostgreSQL heraus zu
bekommen, aber da wir mit PostgreSQL nicht sehr weitgehend vertraut sind,
sind wir sicher, dass wir einige Dinge versäumt haben. Auf der
Benchmark-Seite haben wir genau dokumentiert, wie wir den Benchmark-Test
durchgeführt haben, deshalb sollte es für jeden einfach sein, ihn zu
wiederholen und unsere Ergebnisse zu bestätigen.

Die Benchmarks werden üblicherweise mit und ohne die @code{--fast}-Option
durchgeführt. Wenn wir sie mit @code{--fast} durchführen, versuchen wir,
jeden Trick zu nutzen, den der Server benutzt, um den Code so schnell wie
möglich auszuführen. Die Idee dahinter ist, dass der Server zeigen sollte,
wie er mit Vorgabeeinstellungen läuft und @code{--fast} sollte zeigen, wie
der Server läuft, wenn der Applikationsentwickler Erweiterungen im Server
nutzt, um seine Applikation schneller laufen zu lassen.

Wenn wir PostgreSQL mit der @code{--fast}-Option laufen lassen, machen wir
ein @code{VACUUM()} nach jedem größeren Tabellen-@code{UPDATE} und
@code{DROP TABLE}, um die Datenbank in beste Verfassung für die folgenden
@code{SELECT}s zu bringen. Die Zeit für @code{VACUUM()} wird separat
gemessen.

PostgreSQL 7.1.1 konnten wir jedoch nicht mit der Option @code{--fast}
laufen lassen, weil der Postmaster (der PostgreSQL Daemon) während eines
@code{INSERT}-Tests starb und die Datenbank so beschädigt war, dass es
unmöglich war, den Postmaster neu zu starten. Nachdem dies zweimal
geschehen war, entschieden wir uns, den Test mit @code{--fast} bis zum
nächsten PostgreSQL-Release zu verschieben. Die Details zur Maschine, die
wir für den Benchmark benutzten, stehen auf der Benchmark-Seite.

Bevor wir uns den anderen Benchmarks, die wir kennen, zuwenden, möchten wir
ein paar Hintergrundinformationen zu Benchmarks geben:

Es ist sehr einfach, einen Test zu schreiben, der zeigt, dass JEDE
BELIEBIGE Datenbank die beste der Welt ist, indem man den Test einfach auf
etwas beschränkt, was diese Datenbank sehr gut kann und nichts anderes
testet, was die Datenbank nicht gut kann. Wenn man dann noch das Ergebnis
mittels einer einzigen Zahl veröffentlicht, macht das die Dinge sogar noch
einfacher.

Das wäre, als ob wir die Geschwindigkeit von MySQL gegenüber PostgreSQL
anhand der Messzeit-Zusammenfassung der MySQL-Benchmarks auf unserer
Webseite vergleichen würden. Auf dieser Basis wäre MySQL mehr als 40 Mal
schneller als PostgreSQL, was natürlich nicht stimmt. Wir könnten die Sache
sogar noch verschlimmern, indem wir nur etwas testen, worin PostgreSQL die
schlechtesten Leistungsdaten bringt und geltend machen, dass MySQL mehr als
2000 Mal schneller ist als PostgreSQL.

Tatsache ist, dass MySQL eine Menge Optimierungen vornimmt, die PostgreSQL
nicht vornimmt. Das ist natürlich auch umgekehrt so. Ein SQL-Optimierer ist
eine sehr komplexe Sache, und ein Unternehmen könnte Jahre damit zubringen,
nur den Optimierer schneller und schneller zu machen.

Wenn Sie sich die Ergebnisse der Benchmarks ansehen, sollten Sie nach
Dingen Ausschau halten, die Sie in Ihrer Applikation durchführen, und dann
nur diese Ergebnisse benutzen, um zu entscheiden, welche Datenbank wohl am
besten für Ihre Applikation geeignet ist. Die Benchmark-Ergebnisse zeigen
ausserdem auf, worin eine bestimmte Datenbank nicht gut ist, was Ihnen eine
Ahnung davon geben sollte, welche Dinge Sie am besten vermeiden und was Sie
auf andere Weise machen sollten.

Wir kennen zwei Benchmark-Tests, die behaupten, dass PostgreSQL bessere
Leistungsdaten bringt als MySQL. Beide waren Mehrbenutzer-Tests, ein Test,
den zu schreiben wir bei MySQL AB nie die Zeit hatten, hauptsächlich, weil
es eine wirklich große Aufgabe ist, wenn man will, dass der Test fair zu
allen Datenbanken ist.

Einer der Tests ist derjenige, für den Great Bridge bezahlt hat, und über
den Sie hier lesen können:
@uref{http://www.greatbridge.com/about/press.php?content_id=4}.

Es ist wahrscheinlich der schlechteste Benchmark-Test, den wir jemals
gesehen haben. Er war nicht nur so eingestellt, dass er das testete, was
PostgreSQL absolut am besten kann, er war auch völlig unfair zu jeder
anderen Datenbank, die in diesen Test einbezogen wurde.

@strong{ACHTUNG}: Wir wissen, dass niemand der hauptsächlichen
PostgreSQL-Entwickler die Art mochte, wie Great Bridge den Test
durchgeführt hat, daher geben wir ihnen keinerlei Schuld dafür.

Dieser Benchmark wurde in einer Menge Postings und Newsgroups verurteilt,
daher beschränken wir uns hier darauf, kurz einige Dinge zu wiederholen,
die dabei nicht stimmten.

@itemize @bullet
@item
Die Tests wurden mit einem teuren, kommerziellen Werkzeug durchgeführt, was es
für ein Open-Source-Unternehmen wie uns unmöglich macht, den Benchmark zu
verifizieren, selbst einfach nur zu überprüfen, wie der Benchmark
eigentlich durchgeführt wurde. Das Werkzeug ist nicht einmal ein echtes
Benchmark-Werkzeug, sondern vielmehr ein Applikations-/Setup-Test-Werkzeug. Darauf
als ``Standard''-Benchmark-Werkzeug Bezug zu nehmen heißt, es mit der Wahrheit
nicht so genau zu nehmen.

@item
Great Bridge hat zugegeben, dass sie die PostgreSQL-Datenbank optimiert
haben (mit @code{VACUUM()} vor dem Test) und dass sie das Starten vor dem
Test getuned haben, etwas, das sie für keine der anderen getesteten
Datenbanken gemacht haben. Dazu heißt es: ``Dieser Prozess optimiert
Indexe und gibt etwas Festplattenspeicher frei. Die optimierten Indexe
steigern die Performance um etliches.'' Unsere Benchmarks zeigen deutlich,
dass der Unterschied bei einer großen Menge von Selects auf eine Datenbank
mit und ohne @code{VACUUM()} leicht Faktor zehn betragen kann.

@item
Die Testergebnisse waren ebenfalls merkwürdig. Die AS3AP-Test-Dokumentation
erwähnt, dass der Test ``Auswahlen, einfache Verknüpfungen, Projektionen, 
Aggregierungen, 1-Tupel-Updates und Massen-Updates'' durchführt.

PostgreSQL ist gut bei der Durchführung von @code{SELECT}s und @code{JOIN}s
(speziell nach einem @code{VACUUM()}), performt aber nicht so gut bei
@code{INSERT}s oder @code{UPDATE}s. Die Benchmarks scheinen anzuzeigen,
dass nur @code{SELECT}s durchgeführt wurden (oder sehr wenige Updates). Das
würde die guten Ergebnisse für PostgreSQL in diesem Test erklären. Etwas
weiter unten wird erläutert, wie es zu den schlechten Ergebnissen für MySQL
kam.

@item
Sie ließen den so genannten Benchmark von einer Windows-Maschine zu einer
Linux-Maschine über ODBC laufen, was ein normaler Datenbankbenutzer nie
machen würde, wenn er eine unter hoher Last laufende
Mehrbenutzer-Applikation laufen lassen würde. Dadurch wurde eher der
ODBC-Treiber und das benutzte Windows-Protokoll zwischen den Clients
getestet als die Datenbank selbst.

@item
Als Sie die Datenbank mit Oracle und MS-SQL betrieben (Great Bridge hat
indirekt angedeutet, dass das die Datenbanken waren, die im Test benutzt
wurden), benutzten sie nicht das native Protokoll, sondern statt dessen
ODBC. Jeder, der jemals Oracle benutzt hat, weiß, dass alle echten
Applikationen die native Schnittstelle anstatt ODBC benutzen. Einen Test
mit ODBC fahren und erklären, dass das irgend etwas mit Situationen des
echten Lebens zu tun hat, kann kaum als fair erachtet werden. Sie hätten
zwei Tests fahren sollen: einen mit und einen ohne ODBC, um die korrekten
Fakten zu ermitteln (natürlich, nachdem sie Experten geholt hätten, die
alle getesteten Datenbanken optimal eingestellt hätten).

@item
Sie verweisen auf die TPC-C-Tests, erwähnen aber an keiner Stelle, dass der
Test, den sie fuhren, kein echter TPC-C-Test war und dass es ihnen nicht
einmal erlaubt ist, das einen TPC-C-Test zu nennen. Ein TPC-C-Test darf nur
nach den Regeln durchgeführt werden, die vom TPC-Rat (TPC Council)
festgelegt wurden (@uref{http://www.tpc.org}). Great Bridge hat das nicht
getan. Damit haben sie sowohl das Markenzeichen TPC verletzt als auch ihre
eigenen Benchmarks in Misskredit gebracht. Die Regeln, die vom TPC-Rat
aufgestellt wurden, sind sehr streng, um sicherzustellen, dass niemand
falsche Ergebnisse produziert oder nicht beweisbare Erklärungen abgibt.
Offensichtlich hat das Great Bridge nicht interessiert.

@item
Nach dem ersten Test haben wir Kontakt mit Great Bridge aufgenommen und
ihnen gegenüber einige der offensichtlichen Fehler erwähnt, die sie bei
MySQL gemacht haben:

@itemize @minus
@item
Sie haben MySQL mit einer Debug-Version unseres ODBC-Treibers laufen
lassen.

@item
Sie haben MySQL auf einem Linux-System laufen lassen, das nicht für Threads
optimiert war.

@item
Sie haben eine alte MySQL-Version zu einem Zeitpunkt benutzt, als eine
empfohlene neuere bereits verfügbar war.

@item
Sie haben MySQL nicht mit den richtigen Optionen für hohe Last und
Mehrbenutzerbetrieb gestartet (die vorgabemäßige Installation von MySQL
ist auf minimalen Ressourcenverbrauch eingestellt).
@end itemize

Great Bridge hat einen neuen Test gefahren, wobei zwar unsere optimierten
ODBC-Treiber und bessere Startoptionen für MySQL benutzt wurden, weigerte
sich aber, entweder unsere aktualisierte glibc-Bibliothek oder unsere
Standard-Binärversion (von mehr als 80% unserer Benutzer genutzt) zu
verwenden, sondern benutzte statt dessen eine statisch gelinkte feste
glibc-Bibliothek.

Nach allem, was wir wissen, hat Great Bridge nichts getan, um
sicherzustellen, dass die anderen Datenbanken korrekt konfiguriert wurden,
um in ihrer Testumgebung gut zu laufen. Wir sind jedoch sicher, dass sie
weder Oracle noch Microsoft kontaktiert haben, um sie um Rat in dieser
Angelegenheit zu bitten ;)

@item
Der Benchmark wurde von Great Bridge bezahlt und sie beschlossen, nur
teilweise, ausgewählte Ergebnisse zu veröffentlichen (statt alles publik zu
machen).
@end itemize

Tim Perdue, seit langer Zeit PostgreSQL-Fan und ein widerwilliger
MySQL-Benutzer, hat einen Vergleich auf
@uref{http://www.phpbuilder.com/columns/tim20001112.php3,phpbuilder}
veröffentlicht.

Als wir von diesem Vergleich erfuhren, telefonierten wir mit Tim Perdue zu
diesem Thema, weil es eine Menge merkwürdiger Dinge in seinen Ergebnissen
gab. Er behauptete zum Beispiel, dass MySQL bei seinem Test ein Problem mit
fünf Benutzern hatte, während wir wissen, dass es Benutzer mit ähnlichen
Maschinen wie seine gibt, die MySQL mit 2000 simultanen Verbindungen
betreiben, die 400 Anfragen pro Sekunde abarbeiten. (In diesem Fall war die
Beschränkung durch die Web-Bandbreite gegeben, nicht durch die Datenbank.)

Es schien, als hätte er einen Linux-Kernel benutzt, der entweder Probleme
mit vielen Threads hatte, wie ein Kernel vor Version 2.4, der ein Problem
mit vielen Threads auf Mehrprozessor-Maschinen hat. Wir haben in diesem
Handbuch dokumentiert, wie man das behebt, und Tim sollte sich dieses
Problems bewusst sein.

Das andere mögliche Problem könnte eine alte glibc-Bibliothek gewesen sein,
und dass Tim keine MySQL-Binärdistribution von unserer Site benutzte, die
mit einer korrigierten glibc-Bibliothek gelinkt ist, sondern statt dessen
eine eigene Version kompiliert hat. Bei jedem der genannten Fälle würden
die Symptome genau die sein, die Tim gemessen hat.

Wir haben Tim gebeten, uns Zugang zu seinen Daten zu geben, damit wir den
Benchmark-Test wiederholen könnten, sowie die MySQL-Version auf seiner
Maschine zu prüfen, um herauszufinden, was falsch lief, und er hat
versprochen, uns entsprechende Mitteilung zu geben. Das hat er bis heute
nicht gemacht.

Aus diesem Grund können wir auch diesem Benchmark in keiner Weise vertrauen
:(

Im Zeitverlauf haben sich die Dinge auch geändert und die genannten
Benchmarks sind nicht mehr so relevant. MySQL hat mittlerweile eine Reihe
unterschiedlicher Tabellen-Handler mit unterschiedlichen Verhältnissen
zwischen Geschwindigkeit und Anzahl gleichzeitiger Zugriffe
(Speed/Concurrency Tradeoffs). @xref{Table types}. Es wäre interessant zu
sehen, wie die obigen Tests mit den verschiedenen transaktionalen Tabellen
von MySQL laufen würden. PostgreSQL hat natürlich auch neue Features
erhalten, seit die Tests durchgeführt wurden. Weil die genannten Tests
nicht öffentlich erhältlich sind, gibt es keine Möglichkeit für uns
herauszufinden, wie die Datenbank heute mit denselben Tests laufen würde.


Fazit:

Der einzige Benchmark, der heutzutage existiert, den jeder herunter laden
und laufen lassen kann, um MySQL und PostgreSQL zu vergleichen, ist der
MySQL-Benchmark-Test. Wir hier bei MySQL sind der Überzeugung, dass
Open-Source-Datenbanken mit Open-Source-Werkzeuge getestet werden sollten! Das
ist die einzige Möglichkeit, um sicherzustellen, dass niemand Tests fährt,
die nicht reproduzierbar sind, und diese dazu benutzt, um zu behaupten,
dass eine Datenbank besser sei als die eine andere. Ohne die Fakten zu
kennen ist es unmöglich, auf die Behauptungen des Testers einzugehen.

Eine Sache, die wir merkwürdig finden, ist, dass jeder Test, den wir zu
PostgreSQL gesehen haben - und wo es unmöglich ist, diesen zu wiederholen
-, behauptet, dass PostgreSQL in den meisten Hinsichten besser sei, während
unsere Tests, die jeder reproduzieren kann, eindeutig das Gegenteil
beweisen. Damit wollen wir nicht sagen, dass PostgreSQL nicht vieles sehr
gut kann (das kann es!) oder dass es nicht unter bestimmten Umständen
schneller ist als MySQL. Wir würden nur gern einen fairen Test sehen, der
zeigt, worin PostgreSQL sehr gut ist, damit wir einen freundlichen
Wettbewerb anzetteln können!

Mehr Informationen über unsere Benchmark-Suite finden Sie unter @xref{MySQL Benchmarks}.

Wir arbeiten an einer noch besseren Benchmark-Suite, die Mehrbenutzer-Tests
beinhaltet sowie eine bessere Dokumentation dessen, was die einzelnen Tests
genau tun und wie man weitere Tests zur Suite hinzufügt.

@node Installing, Tutorial, Deutsch, Top
@c German node Installation
@chapter Installation von MySQL

@cindex Installation, Überblick


Dieses Kapitel beschreibt, woher man MySQL bezieht und wie man MySQL
installiert:

@itemize @bullet
@item
Eine Liste der Site, von denen Sie MySQL beziehen können, finden Sie unter
@ref{Getting MySQL, , Wie man MySQL erhält}.

@item
@c German FIX unsplit @ref
Um festzustellen, welche Plattformen unterstützt werden, siehe
@ref{Which OS}. Beachten Sie bitte, dass nicht alle
unterstützten Systeme gleich gut
sind, um MySQL laufen zu lassen. Auf einigen läuft es sehr viel robuster
und effizienter als auf anderen - siehe @ref{Which OS} für
Details.

@item
Mehrere Versionen von MySQL sind sowohl als Binär- als auch als
Quellcode-Distributionen erhältlich. Wir stellen auch öffentlichen Zugriff
auf unseren aktuellen Quellcode-Baum für diejenigen zur Verfügung, die die
aktuellsten Entwicklungen sehen und uns helfen wollen, neuen Code zu
testen. Um festzustellen, welche Version und welche Art von Distribution Sie
benutzen sollten, siehe @ref{Which version}. Im Zweifelsfall benutzen Sie
die Binärdistribution.

@item
Installationsanleitungen für Binär- und Quelldistributionen sind
beschrieben in @ref{MySQL binaries} und @ref{Installing source}. Jede
Anleitung enthält einen Abschnitt über System-spezifische Probleme, denen
Sie begegnen können.

@item
Prozeduren, die nach der Installation durchgeführt werden sollen / müssen,
finden Sie unter @ref{Post-installation}. Diese Prozeduren gelten, egal ob
Sie MySQL von einer Binär- oder einer Quellcode-Distribution installieren.
@end itemize


@menu
* Quick Standard Installation::  
* General Installation Issues::  
* Installing source::           
* Post-installation::           
* Upgrade::                     
* Operating System Specific Notes::  
* Perl support::                
@end menu

@node Quick Standard Installation, General Installation Issues, Installing, Installing
@c German node Schnelle Standard-Installation
@section Schnelle Standard-Installation von MySQL

@c This node name ist special


@menu
* Linux-RPM::                   
* Windows installation::        
@end menu

@node Linux-RPM, Windows installation, Quick Standard Installation, Quick Standard Installation
@c German node Linux-RPM
@subsection MySQL auf Linux installieren

@cindex RPM-Datei
@cindex RedHat Package Manager

Die empfohlene Vorgehensweise für die Installation von MySQL auf Linux ist
die Benutzung einer RPM-Datei. Die MySQL-RPMs werden aktuell auf einer
RedHat-Version 6.2 gebaut, sollten aber auch auf anderen Linux-Versionen
funktionieren, die @code{rpm} unterstützen und @code{glibc} benutzen.

Wenn Sie Probleme mit einer RPM-Datei haben, wenn Sie beispielsweise den
Fehler ``@code{Sorry, the host 'xxxx' could not be looked up}'' erhalten,
sehen Sie bitte unter @ref{Linux-RPM} nach.

Die RPM-Dateien, die Sie benutzen sollten, sind:

@itemize @bullet
@item @code{MySQL-VERSION.i386.rpm}

Der MySQL-Server. Sie brauchen diese, es sei denn, Sie wollen sich
lediglich mit einem MySQL-Server verbinden, der auf einer anderen Maschine
läuft.

@item @code{MySQL-client-VERSION.i386.rpm}

Die Standard-MySQL-Client-Programme. Dieses Paket sollten Sie wohl immer
installieren.

@item @code{MySQL-bench-VERSION.i386.rpm}

Tests und Benchmarks. Erfordert Perl und msql-mysql-modules RPMs.

@item @code{MySQL-devel-VERSION.i386.rpm}

Bibliotheken und Include-Dateien, die benötigt werden, wenn Sie andere
MySQL-Clients kompilieren wollen, beispielsweise Perl-Module.

@item @code{MySQL-VERSION.src.rpm}

Dieses Paket enthält den Quelltext für alle obigen Pakete. Es kann auch
dazu benutzt werden, um RPMs für andere Architekturen zu bauen (zum
Beispiel für Alpha oder SPARC).
@end itemize

Um alle Dateien in einem RPM-Paket zu sehen, geben Sie folgendes ein:
@example
shell> rpm -qpl MySQL-VERSION.i386.rpm
@end example

Um eine minimale Standard-Installation durchzuführen, geben Sie folgendes
ein:

@example
shell> rpm -i MySQL-VERSION.i386.rpm MySQL-client-VERSION.i386.rpm
@end example

Um nur das Client-Paket zu installieren, geben Sie folgendes ein:

@example
shell> rpm -i MySQL-client-VERSION.i386.rpm
@end example

Das RPM legt Dateien in @file{/var/lib/mysql} ab. Ausserdem erzeugt das RPM
die entsprechenden Einträge in @file{/etc/rc.d/}, um den Server beim Booten
automatisch zu starten. (Falls Sie bereits vorher eine Installation
durchgeführt haben, bedeutet das, dass Sie eine Kopie Ihrer vorher
installierten MySQL-Startdateien machen sollten, falls Sie darin Änderungen
vorgenommen haben, damit Sie diese Änderungen nicht verlieren.)

Nach der Installation der RPM-Datei(en) sollte der @code{mysqld}-Daemon
laufen und Sie sollten jetzt in der Lage sein, mit der Benutzung von MySQL
zu beginnen. @xref{Post-installation}.

Wenn etwas schief geht, finden Sie weitere Informationen im Kapitel über
die Binär-Installationen. @xref{MySQL binaries}.

@node Windows installation,  , Linux-RPM, Quick Standard Installation
@c German node Windows-Installation
@subsection Installation von MySQL unter Windows

Der MySQL-Server für Windows ist in zwei Distributionstypen erhältlich:
@enumerate
@item
Die Binärdistribution enthält ein Setup-Programm, das alles Benötigte
installiert, so dass Sie den Server sofort starten können.
@item
Die Quelldistribution enthält den gesamten Code und
Unterstützungsdateien, um die ausführbaren Dateien unter Benutzung des
VC++-6.0-Kompilers zu bauen.
@xref{Windows source build}.
@end enumerate

Im Allgemeinen sollten Sie die Binärdistribution benutzen.

Sie benötigen folgendes:
@itemize @bullet
@item
Ein Windows-32-Bit-Betriebssystem der Familien Windows 9x, ME, NT oder
Windows 2000. Die NT-Familie gestattet, den MySQL-Server als
Systemdienst laufen zu lassen. @xref{NT start}.

Wenn Sie Tabellen benutzen, die größer als 4 GB sind, sollten Sie MySQL
auf NTFS oder einem neueren Dateisystem installieren. Vergessen Sie bei
der Erzeugung der Tabellen nicht, @code{MAX_ROWS} und
@code{AVG_ROW_LENGTH} zu benutzen. @xref{CREATE TABLE}.
@item
TCP/IP-Protokollunterstützung.
@item
Die MySQL-Binär- oder Quelldistribution für Windows kann von
@uref{http://www.mysql.com/downloads/} herunter geladen werden.

Hinweis: Die Distributionsdateien werden in einem komprimierten Format
zur Verfügung gestellt. Wir empfehlen die Benutzung eines FTP-Clients,
der in der Lage ist, abgebrochene FTP-Downloads wieder aufzunehmen
(resume).
@item
Ein @code{ZIP}-Programm, um die Distributionsdatei zu entpacken.
@item
Genug Platz auf der Festplatte, um die Datenbanken entsprechend Ihren
Anforderungen zu entpacken, zu installieren und zu erzeugen.
@item
Wenn Sie planen, sich über @code{ODBC} mit dem MySQL-Server zu
verbinden, benötigen Sie zusätzlich den @code{MyODBC}-Treiber.
@xref{ODBC}.
@end itemize



@menu
* Windows binary installation::  
@end menu

@node Windows binary installation,  , Windows installation, Windows installation
@c German node Windows-Binärinstallation
@subsubsection Binärdateien installieren

@enumerate
@item
Wenn Sie auf einem NT- oder Windows-2000-Server arbeiten, melden Sie
sich als Benutzer mit Administrationsrechten an.
@item
Wenn Sie ein Upgrade einer früheren MySQL-Installation durchführen,
müssen Sie den Server anhalten. Wenn Sie den Server als Systemdienst
laufen lassen, geben Sie ein:

@example
C:\> NET STOP MySQL
@end example

Ansonsten geben Sie folgendes ein:

@example
C:\mysql\bin> mysqladmin -u root shutdown
@end example

@item
Auf NT-/Windows-2000-Maschinen müssen Sie auch den Systemdienst
entfernen, wenn Sie die ausführbare Datei des Servers (z. B. -max or -nt) austauschen wollen:

@example
C:\mysql\bin> mysqld-max-nt --remove
@end example

@item
Entpacken Sie die Distributionsdatei in ein temporäres Verzeichnis.
@item
Starten Sie @file{setup.exe}, um den Installationsprozess zu beginnen.
Wenn Sie in ein anderes Verzeichnis als das vorgabemäßige
(@file{c:\mysql}) installieren wollen, legen Sie mit der Schaltfläche
@code{Durchsuchen} das gewünschte Verzeichnis fest.
@item
Beenden Sie den Installationsprozess.
@end enumerate


Seit MySQL 3.23.38 enthält die Windows-Distribution sowohl die normalen als
auch die @strong{MySQL-Max}-Binärdateien. Der wichtigste Vorteil der
Benutzung der normalen @code{mysqld.exe}-Binärdatei liegt darin, dass sie
etwas schneller ist und weniger Ressourcen belegt.

Hier ist eine Liste der unterschiedlichen MySQL-Server, die Sie benutzen
können:
@multitable @columnfractions .25 .75
@item @code{mysqld} @tab Kompiliert mit komplettem Debugging und automatischer Überprüfung der Speicherzuordnung (memory allocation), symbolischen Links, InnoDB- und BDB-Tabellen.
@item @code{mysqld-opt} @tab Optimierte Binärdistribution ohne Unterstützung von Transaktionstabellen.
@item @code{mysqld-nt} @tab Optimierte Binärdatei für NT mit Unterstützung von Named Pipes. Man kann diese Version auf Windows 98 laufen lassen, aber in diesem Fall werden keine Named Pipes angelegt und man muss TCP/IP installiert haben.
@item @code{mysqld-max} @tab Optimierte Binärdistribution mit Unterstützung symbolischer Links, InnoDB und BDB-Tabellen.
@item @code{mysqld-max-nt} @tab Wie @code{mysqld-max}, aber mit Unterstützung von Named Pipes kompiliert.
@end multitable

Alle genannten Binärdistributionen sind für den Pentium Pro Prozessor
optimiert, sollten aber auf jedem Intel-Prozessor >= 386 laufen.

ACHTUNG: Wenn Sie InnoDB-Tabellen benutzen wollen, müssen Sie bestimmte
Start-Optionen in Ihrer @file{my.ini}-Datei festlegen! @xref{InnoDB start}.


@node General Installation Issues, Installing source, Quick Standard Installation, Installing
@c German node Allgemeine Installationsthemen
@section Allgemeine Installationsthemen

@c @node Methods of Installation, , ,
@c @subsection Installationsmethoden

@c FIX: this needs to be written? 



@menu
* Getting MySQL::               
* Which OS::                    
* Which version::               
* Installation layouts::        
* Many versions::               
* MySQL binaries::              
@end menu

@node Getting MySQL, Which OS, General Installation Issues, General Installation Issues
@c German node Wie man MySQL erhält
@subsection Wie man MySQL erhält

@cindex Download
@cindex MySQL-Version
@cindex Version, aktuelle
@cindex Wie man MySQL erhält
@cindex Mirror-Sites
@cindex URLS zum Download von MySQL

Sehen Sie wegen Informationen zur aktuellen Version und für
Download-Anweisungen auf @uref{http://www.mysql.com/, MySQL home page}
nach.

Unser Haupt-Mirror-Server für den Download ist hier:

@uref{http://mirrors.sunsite.dk/mysql/}

Wenn Sie Interesse haben, eine MySQL-Mirror-Site beizusteuern, können Sie
anonymes rsync mit @code{rsync://sunsite.dk/ftp/mirrors/mysql/} machen.
Schicken Sie bitte eine E-Mail an @email{webmaster@@mysql.com} und geben
Sie uns Bescheid, wo Ihr Mirror liegt, damit wir ihn der unten stehenden
Liste hinzufügen können.

Wenn Sie Probleme beim Download von unserer Hauptseite aus haben, probieren
Sie eine der unten stehenden Mirror-Sites.

Geben Sie bitte @email{webmaster@@mysql.com} Bescheid, wenn Sie auf
schlechte oder veraltete Mirror-Sites stoßen.

@c START_OF_MIRROR_LISTING

@c German FIX added include of mirror listing (old German text was bad Texinfo)

@c Mirrors list is created by PHP script (that really needs to be documented!) from database (tfr@mysql.com)
@include mirrors.texi

@c END_OF_MIRROR_LISTING


@node Which OS, Which version, Getting MySQL, General Installation Issues
@c German node Welches Betriebssystem
@subsection Betriebssysteme, die von MySQL unterstützt werden

@cindex Betriebssysteme, unterstützte
@cindex Native Thread-Unterstützung
@cindex Thread-Unterstützung
@cindex Prozess-Unterstützung
@cindex Unterstützung, für Betriebssysteme

Wir benutzen GNU Autoconf, daher ist es möglich, MySQL auf alle modernen
Betriebssysteme zu portieren, auf denen Posix-Threads und ein C++-Kompiler
funktionieren. (Um nur den Client-Code zu kompilieren, wir lediglich ein
C++-Kompiler benötigt.) Wir benutzen und entwickeln die Software selbst
hauptsächlich auf Sun Solaris (Versionen 2.5 - 2.7) und SuSE Linux Version
7.x.

Beachten Sie, dass die native Thread-Unterstützung für viele
Betriebssysteme nur mit den neuesten Versionen funktioniert. Es wurde
berichtet, dass MySQL erfolgreich auf folgenden Betriebssystemen /
Thread-Paket-Kombinationen kompiliert wurde:

@itemize @bullet
@item
AIX 4.x mit nativen Threads.  @xref{IBM-AIX}.
@item
Amiga.
@item
BSDI 2.x mit enthaltenem MIT-pThreads-Paket.  @xref{BSDI}.
@item
BSDI 3.0, 3.1 und 4.x mit nativen Threads.  @xref{BSDI}.
@item
DEC Unix 4.x mit nativen Threads.  @xref{Alpha-DEC-UNIX}.
@item
FreeBSD 2.x mit enthaltenem MIT-pThreads-Paket.  @xref{FreeBSD}.
@item
FreeBSD 3.x und 4.x mit nativen Threads.  @xref{FreeBSD}.
@item
HP-UX 10.20 mit enthaltenem MIT-pThreads-Paket.  @xref{HP-UX 10.20}.
@item
HP-UX 11.x mit nativen Threads.  @xref{HP-UX 11.x}.
@item
Linux 2.0+ mit LinuxThreads 0.7.1+ oder @code{glibc} 2.0.7+.  @xref{Linux}.
@item
Mac OS X Server.  @xref{Mac OS X}.
@item
NetBSD 1.3/1.4 Intel und NetBSD 1.3 Alpha (benötigt GNU make).  @xref{NetBSD}.
@item
OpenBSD > 2.5 mit nativen Threads. OpenBSD < 2.5 mit enthaltenem
MIT-pThreads-Paket.  @xref{OpenBSD}.
@item
OS/2 Warp 3, FixPack 29 und OS/2 Warp 4, FixPack 4.  @xref{OS/2}.
@item
SGI Irix 6.x mit nativen Threads.  @xref{SGI-Irix}.
@item
Solaris 2.5 und höher mit nativen Threads auf SPARC und x86.  @xref{Solaris}.
@item
SunOS 4.x mit enthaltenem MIT-pThreads-Paket.  @xref{Solaris}.
@item
Caldera (SCO) OpenServer mit einem aktuellen Port des FSU-PThreads-Pakets.  @xref{Caldera}.
@item
Caldera (SCO) UnixWare 7.0.1.  @xref{Caldera Unixware}.
@item
Tru64 Unix
@item
Windows 95, Windows 98, NT und Windows 2000.  @xref{Windows}.
@end itemize

Beachten Sie, dass nicht alle Plattformen gleichermaßen gut geeignet sind,
um MySQL laufen zu lassen. Wie gut eine bestimmte Plattform für hohe Last
und geschäftskritische Anwendungen geeignet ist, hängt von folgenden
Faktoren ab:

@itemize @bullet
@item
Allgemeine Stabilität der Thread-Bibliothek. Eine Plattform mag in anderer
Hinsicht einen exzellenten Ruf haben, aber wenn die Thread-Bibliothek
unstabil ist, die von MySQL aufgerufen wird, läuft MySQL nur so stabil wie
die Thread-Bibliothek, selbst wenn alles Sonstige perfekt ist.

@item
Fähigkeit des Kernels und / oder der Thread-Bibliothek, die Vorteile von
@strong{SMP} auf Mehrprozessor-Systemen wahrzunehmen. Mit anderen Worten:
Wenn ein Prozess einen Thread anlegen, sollte es für diesen Thread möglich
sein, auf anderen Prozessoren zu laufen als der Original-Prozess.

@item
Fähigkeit des Kernels und / oder der Thread-Bibliothek, viele Threads
laufen zu lassen, die häufig einen Mutex über eine kurze, kritische Region
anlegen / lösen können ohne exzessive Kontext-Umschaltungen. Mit anderen
Worten: Wenn die Implementation von @code{pThread_mutex_lock()} zu sehr
darauf bedacht ist, CPU zu erlangen, wird das MySQL gewaltig schmerzen.
Wenn man sich dieser Tatsache nicht bewusst ist, machen zusätzliche
Prozessoren MySQL in der Tat langsamer.

@item
Allgemeine Stabilität und Performance des Dateisystems.

@item
Fähigkeit des Dateisystems, überhaupt mit großen Dateien umgehend zu
können, und zwar effizient, wenn Ihre Tabellen Groß sind.

@item
Unser Grad von Erfahrung, hier bei MySQL AB, mit der Plattform. Wenn wir
eine Plattform gut kennen, setzen wir plattformspezifische Optimierungen /
Verbesserungen (Fixes) ein, die zur Kompilierzeit aktiv werden. Darüber
hinaus können wir Sie beraten, wie Sie Ihr System optimal für MySQL
konfigurieren.

@item
Umfang des Testens ähnlicher Konfigurationen, das wir intern durchgeführt
haben.

@item
Anzahl von Benutzern, die MySQL auf dieser Plattform erfolgreich mit
ähnlichen Konfigurationen haben laufen lassen. Wenn diese Zahl Groß ist,
ist die Wahrscheinlichkeit viel geringer, plattformspezifische
Überraschungen zu erleben.
@end itemize

Nach den genannten Kriterien sind die besten Plattformen für MySQL bislang
x86 mit SuSE Linux 7.1, 2.4 Kernel und ReiserFS (oder jede ähnliche
Linux-Distribution) und Sparc mit Solaris 2.7 oder 2.8. FreeBSD kommt als
drittes, aber wir hoffen wirklich, dass es zur Spitze aufschließt, sobald
erst einmal die Thread-Bibliothek verbessert ist. Wir hoffen auch, dass wir
alle anderen Plattformen, auf denen MySQL kompiliert werden kann und
korrekt läuft, die aber nicht ganz denselben Grad an Stabilität und
Performance aufweisen, in die Spitzenkategorie aufnehmen können. Das
erfordert von unserer Seite aus einige Kooperationsbemühungen mit den
Entwicklern der Betriebssystem-Bibliothek-Komponenten, von denen MySQL
abhängt. Wenn Sie Interesse daran haben, eine dieser Komponenten zu
verbessern und in der Lage sind, ihre Entwicklung zu beeinflussen, und
detailliertere Informationen darüber brauchen, was MySQL benötigt, um
besser zu laufen, schicken Sie eine E-Mail an
@email{internals@@lists.mysql.com}.

Beachten Sie bitte auch, dass der obige Vergleich nichts darüber aussagen
will, dass ein Betriebssystem allgemein besser oder schlechter als ein
anderes sei. Wir reden hier über die Auswahl eines bestimmten
Betriebssystems für einen ganz bestimmten Zweck - nämlich, MySQL laufen zu
lassen, und vergleichen die Betriebssysteme nur in dieser Hinsicht.
Folglich wäre das Ergebnis dieses Vergleichs ein anderes, wenn wir weitere
Belange berücksichtigen würden. In manchen Fällen liegt der Grund, warum
ein Betriebssystem besser als ein anderes geeignet ist, schlicht darin,
dass wir auf dieser speziellen Plattform mehr Tests und Optimierungen
durchgeführt haben. Wir stellen hier nur unsere Beobachtungen dar, um Ihnen
bei der Entscheidung zu helfen, auf welcher Plattform Sie MySQL benutzen
sollten.


@node Which version, Installation layouts, Which OS, General Installation Issues
@c German node Welche Version
@subsection Welche MySQL-Version Sie benutzen sollten

@cindex MySQL-Binärdistribution
@cindex MySQL-Quelldistribution
@cindex Release-Nummer
@cindex Version, Auswahl
@cindex Auswahl, einer MySQL-Version

Zunächst müssen Sie entscheiden, ob Sie das letzte Entwicklungs-Release
oder das letzte stabile Release benutzen wollen:

@itemize @bullet
@item
Normalerweise, wenn Sie MySQL zum ersten Mal benutzen, oder wenn Sie
versuchen, MySQL auf ein System zu portieren, für das es keine
Binärdistribution gibt, empfehlen wir, das stabile Release zu nehmen
(aktuell Version @value{mysql_version}). Beachten Sie, dass alle
MySQL-Releases mit den MySQL-Benchmarks und einer umfassenden Test-Suite
getestet sind, bevor das Release heraus gegeben wird.

@item
Wenn Sie ein altes System laufen lassen und es aktualisieren möchten, aber
nicht riskieren wollen, dass ein Update nicht reibungslos klappt, sollten
Sie zur aktuellsten Version des Zweiges aktualisieren, den Sie benutzen
(bei dem nur die letzte Versionsnummer neuer ist als Ihre, also z. B. von
3.23.36 auf 3.23.44, wenn 3.23.44 die neueste Version des Zweigs ist). Wir
haben uns innerhalb der Versions-Zweige bemüht, nur schwere Fehler zu
beseitigen und kleine, relativ sichere Änderungen zu machen.
@end itemize

Als nächstes müssen Sie entscheiden, ob Sie eine Quelldistribution oder
eine Binärdistribution nehmen wollen. In den meisten Fällen ist es ratsam,
eine Binärdistribution zu nehmen, wenn eine für Ihre Plattform existiert,
weil sich diese im Allgemeinen leichter installieren läßt als eine
Quelldistribution.

In folgenden Fällen fahren Sie mit einer Quellinstallation wahrscheinlich
besser:

@itemize @bullet
@item
Wenn Sie MySQL an einer ganz bestimmten Stelle installieren wollen. (Die
Standard-Binärdistributionen sind an jeder Stelle lauffähig, aber
vielleicht wollen Sie noch mehr Flexibilität haben.)

@item
Um unterschiedlichen Bedürfnissen von Benutzern entgegen zu kommen, stellen
wir zwei unterschiedliche Binärversionen zur Verfügung: Eine, die mit den
nicht transaktionalen Tabellen-Handlern kompiliert ist (eine kleine,
schnelle Binärdatei), sowie eine, die mit den wichtigsten erweiterten
Optionen wie transaktionssicheren Tabellen kompiliert ist. Beide Versionen
sind aus derselben Quelldistribution kompiliert. Alle nativen
@code{MySQL}-Clients können sich mit beiden MySQL-Versionen verbinden.

Die erweiterte MySQL-Binärdistribution ist mit dem @code{-max}-Suffix
gekennzeichnet und ist mit denselben Optionen konfiguriert wie
@code{mysqld-max}. @xref{mysqld-max, , @code{mysqld-max}}.

Wenn Sie das @code{MySQL-Max}-RPM benutzen wollen, müssen Sie zuerst das
Standard-@code{MySQL}-RPM installieren.

@item
Wenn Sie @code{mysqld} mit einigen zusätzlichen Features konfigurieren
wollen, die NICHT in den Standard-Binärdistributionen enthalten sind. Hier
ist eine Liste der gebräuchlichsten Zusatzoptionen, die Sie vielleicht
nutzen wollen:

@itemize @bullet
@item @code{--with-berkeley-db}
@item @code{--with-innodb}
@item @code{--with-raid}
@item @code{--with-libwrap}
@item @code{--with-named-z-lib  (ist in einigen Binärdateien enthalten)}
@item @code{--with-debug[=full]}
@end itemize

@item
Die vorgabemäßige Binärdistribution wird normalerweise mit Unterstützung
für alle Zeichensätze kompiliert und sollte auf einer Vielzahl von
Prozessoren derselben Prozessorfamilie laufen.

Wenn Sie einen schnelleren MySQL-Server erhalten wollen, können Sie ihn
erneut kompilieren und nur die Zeichensätze benutzen, die Sie brauchen. Sie
können auch einen besseren Kompiler (wie @code{pgcc}) oder andere
Kompilieroptionen benutzen, die besser auf Ihren Prozessor optimiert sind.

@item
Wenn Sie einen Bug gefunden und dem MySQL-Entwicklungsteam mitgeteilt
haben, werden Sie wahrscheinlich einen Patch erhalten, den Sie mit der
Quelldistribution verwenden müssen, um den Bug zu beheben.

@item
Wenn Sie den C- und C++-Code lesen (und / oder ändern) wollen, aus dem
MySQL besteht, müssten Sie eine Quelldistribution laden. Der Quellcode ist
immer das ''letzte Handbuch''. Quelldistributionen enthalten auch mehr
Tests und Beispiele als Binärdistributionen.
@end itemize

@cindex naming, releases of MySQL
@cindex Releases, Benennungsschema

Das MySQL Benennungsschema benutzt Release-Nummern, die aus drei Zahlen und
einem Suffix bestehen. Ein Release-Name wie @code{mysql-3.21.17-beta} zum
Beispiel wird wie folgt interpretiert:

@itemize @bullet
@item
Die erste Zahl (@code{3}) beschreibt das Dateiformat. Alle
Version-3-Releases haben dasselbe Dateiformat.

@item
Die zweite Zahl (@code{21}) ist die Release-Ebene (Level). Normalerweise
kann man hier zwischen zweien auswählen. Einer ist der stabile Zweig des
Releases (aktuell @code{23}), der andere ist der Entwicklungs-Zweig
(aktuell @code{4.0}). Normalerweise sind beide stabil, aber die
Entwicklungsversion kann Macken oder fehlende Dokumentation neuer Features
haben oder sich auf einigen Systemen nicht kompilieren lassen.

@item
Die dritte Zahl (@code{17}) ist die Versionsnummer innerhalb der
Release-Ebene. Diese wird für jede neue Distribution hochgezählt.
Üblicherweise werden Sie die neueste Version der Release-Ebene einsetzen
wollen, die Sie gewählt haben.

@item
Das Suffix (@code{beta}) zeigt den Stabilitätsgrad des Releases an.
Mögliche Suffixe sind:

@itemize @minus
@item 
@code{alpha} zeigt an, dass das Release größere Abschnitte von neuem Code
enthält, der noch nicht zu 100% getestet wurde. Bekannte Bugs
(üblicherweise gibt es keine) sind im News-Abschnitt dokumentiert.
@xref{News}. In den meisten Alpha-Releases gibt es neue Befehle und
Erweiterungen. Bei einem Alpha-Release können durch aktive
Weiterentwicklung größere Code-Änderungen vorkommen, aber alles wird
getestet, bevor ein Release veröffentlicht wird. Es sollte in keinem
MySQL-Release bekannte Bugs geben.

@item
@code{beta} bedeutet, dass jeglicher neue Code getestet wurde. Es wurden
keine neuen Features hinzugefügt, die bei altem Code Probleme verursachen
könnten. Es sollte keine bekannten Bugs geben. Eine Version wird von Alpha
auf Beta gesetzt, wenn innerhalb der Alpha-Version mindestens einen Monat
lang keine schweren Fehler mehr berichtet wurden. Wir planen für eine
solche Version dann keine neuen Features mehr, die einen alten Befehl
unzuverlässiger machen könnten.

@item
@code{gamma} ist eine Beta-Version, die eine ganze Weile draussen war und
offensichtlich gut funktioniert. Nur kleinere Problembehebungen wurden
hinzugefügt. So etwas nennen viele andere Unternehmen ein Release.

@item
Wenn eine Version kein Suffix besitzt, bedeutet das, dass diese Version
schon eine ganze Weile auf vielen unterschiedlichen Sites eingesetzt wird,
wobei keine Bugs ausser plattformspezifischen Bugs berichtet wurden. Für
ein solches Release werden nur kritische Fehlerbehebungen durchgeführt. So
etwas nennen wir ein stabiles Release.
@end itemize
@end itemize

Alle Versionen von MySQL laufen durch unsere Standard-Tests und
-Benchmarks, um sicherzustellen, dass man sie relativ sicher benutzen kann.
Weil die Standard-Tests im Laufe der Zeit erweitert werden, um auf alle
früher gefundenen Bugs zu prüfen, wird die Test-Suite immer besser.

@cindex releases, testing
@cindex Testen, von MySQL-Releases

Beachten Sie, dass alle Releases mindestens wie folgt getestet wurden:

@table @asis
@item Mit der internen Test-Suite
Diese ist Teil unseres Produktionssystems für einen Kunden. Sie besitzt
viele Tabellen mit Hunderten Megabytes an Daten.

@item Mit der MySQL-Benchmark-Suite
Diese läßt eine Reihe gebräuchlicher Anfragen laufen. Das ist zusätzlich
ein Test darauf, ob die letzten Optimierungen den Code tatsächlich
schneller gemacht haben.
@xref{MySQL Benchmarks}.

@item Mit dem @code{crash-me}-Test
Dieser Test versucht festzustellen, welche Features die Datenbank
unterstützt und was ihre Fähigkeiten und Beschränkungen sind. @xref{MySQL Benchmarks}.
@end table

Ein weiterer Test besteht darin, dass wir die neueste MySQL-Version in
unserer internen Entwicklungsumgebung einsetzen, mindestens auf einer
Maschine. Wir arbeiten hierbei mit mehr als 100 Gigabytes an Daten.


@node Installation layouts, Many versions, Which version, General Installation Issues
@c German node Installationslayouts
@subsection Installationslayouts

@cindex Installationslayouts
@cindex Layout der Installation
@cindex Verzeichnisstruktur, Vorgabe
@cindex Vorgabemäßiger Installationsort

Dieser Abschnitt beschreibt das vorgabemäßige Layout der Verzeichnisse,
die durch die Installation von Binär- und Quelldistributionen angelegt
werden.

Eine Binärdistribution wird installiert, indem sie an die
Installationsstelle entpackt wird, die Sie auswählen (typischer Weise
@file{/usr/local/mysql}). Die Installation erstellt folgende Verzeichnisse
an dieser Stelle:

@multitable @columnfractions .3 .7
@item @strong{Verzeichnis} @tab @strong{Verzeichnisinhalt}
@item @file{bin}           @tab Client-Programme und der
@code{mysqld}-Server
@item @file{data}          @tab Log-Dateien, Datenbanken
@item @file{include}       @tab Include-(Header)-Dateien
@item @file{lib}           @tab Bibliotheken
@item @file{scripts}       @tab @code{mysql_install_db}
@item @file{share/mysql}   @tab Dateien mit Fehlernachrichten
@item @file{sql-bench}     @tab Benchmarks
@end multitable

Eine Quelldistribution wird installiert, nachdem Sie sie konfiguriert und
kompiliert haben. Vorgabemäßig werden Dateien unter @file{/usr/local}
installiert, und zwar in den folgenden Unterverzeichnissen:

@multitable @columnfractions .3 .7
@item @strong{Verzeichnis} @tab @strong{Verzeichnisinhalt}
@item @file{bin}           @tab Client-Programme und -Skripte
@item @file{include/mysql} @tab Include-(Header)-Dateien
@item @file{info}	   @tab Dokumentation im Info-Format
@item @file{lib/mysql}     @tab Bibliotheken
@item @file{libexec}       @tab Der @code{mysqld}-Server
@item @file{share/mysql}   @tab Dateien mit Fehlernachrichten
@item @file{sql-bench}     @tab Benchmarks und @code{crash-me}-Test
@item @file{var}           @tab Datenbanken und Log-Dateien
@end multitable

Innerhalb eines Installationsverzeichnisses weicht das Layout einer
Quellinstallation von dem einer Binärinstallation wie folgt ab:

@itemize @bullet
@item
Der @code{mysqld}-Server wird in das @file{libexec}-Verzeichnis installiert
und nicht in das @file{bin}-Verzeichnis.

@item
Das Daten-Verzeichnis ist @file{var} und nicht @file{data}.

@item
@code{mysql_install_db} wird in das @file{/usr/local/bin} Verzeichnis
installiert und nicht in @file{/usr/local/mysql/Skripts}.

@item
Die Header-Datei und Bibliotheksverzeichnisse sind @file{include/mysql} und
@file{lib/mysql} und nicht @file{include} und @file{lib}.
@end itemize

Sie können Ihre eigene Binärinstallation aus einer kompilierten
Quelldistribution erzeugen, indem Sie das Skript
@file{Skripts/make_binary_Distribution} ausführen.


@node Many versions, MySQL binaries, Installation layouts, General Installation Issues
@c German node Viele Versionen
@subsection Wann und wie Updates veröffentlicht werden

@cindex Releases, Updates
@cindex Updates, Releases von MySQL

MySQL entwickelt sich ziemlich schnell hier bei MySQL AB und wir wollen,
dass andere MySQL-Benutzer daran teilhaben. Wir versuchen, immer dann ein
neues Release heraus zu bringen, wenn wir sehr nützliche Features haben,
für die offensichtlich ein Bedarf besteht.

Auch versuchen wir, unseren Benutzern zu helfen, wenn Sie nach Features
anfragen, die einfach zu implementieren sind. Wir notieren, was unsere
lizensierten Nutzer haben wollen, und insbesondere, was unsere Benutzer mit
erweitertem E-Mail-Support haben wollen, und versuchen ihnen, eben das zu
bieten.

Niemand muss einen neuen Release herunter laden. Im News-Abschnitt steht
stets, ob das neue Release etwas beinhaltet, was Sie wirklich brauchen.
@xref{News}.

Wenn wir MySQL aktualisieren, fahren wir folgende Politik:

@itemize @bullet
@item
Bei kleineren Updates wird die letzte Zahl (von rechts) in der
Versionsnummer herauf gezählt (Minor Release). Wenn es größere neue
Features gibt oder kleinere Inkompatibilitäten mit vorherigen Versionen,
wird die zweite Zahl der Versionsnummer herauf gezählt (Major Release).
Wenn sich das Dateiformat ändert, wird die erste Zahl herauf gezählt.

@item
@c Question: This is supposed to mean "stable major releases". What does it
have to do with "small bugs" => minor releases?
Stable tested releases are meant to appear about 1-2 times a year, but
if small bugs are found, a release mit only bug fixes will be released.
Als stabil getestete Releases sollten etwa ein- bis zweimal im Jahr
erscheinen, aber wenn kleinere Fehler gefunden werden, wird nur ein Release
mit Bug-Fixes heraus gegeben.


@item
Funktionierende Releases sollten etwa alle 1 bis 8 Wochen erscheinen.

@item
Binärdistributionen für einige Plattformen werden von uns für größere
Releases (Major) heraus gegeben. Andere Leute stellen vielleicht auch
Binärdistributionen für andere Systeme her, aber nicht so häufig.

@item
Patches stellen wir üblicherweise zur Verfügung, sobald wir kleinere Bugs
ausfindig gemacht und behoben haben.

@item
Für nicht kritische, aber störende Bugs machen wir Patches verfügbar, wenn
sie uns zugesandt werden. Ansonsten kombinieren wir mehrere davon in einem
größeren Patch.

@item
Wenn durch unglückliche Umstände ein Release einen schweren Fehler enthält,
erstellen wir sobald wie möglich ein neues Release. Das würden wir auch
gern bei anderen Unternehmen so sehen.
@end itemize


@c Question: I will not translate this paragraph now. Please update this!
The current stable release ist Version 3.23; We have already moved active
Entwicklung to Version 4.0.  Bugs will still be fixed in the stable version.
We don't believe in a complete freeze, as this also leaves out bug fixes
und things that ``must be done.''  ``Somewhat frozen'' means that we may
add small things that ``almost surely will not affect anything that's
already working.''


@node MySQL binaries,  , Many versions, General Installation Issues
@c German node MySQL-Binärdistributionen
@subsection MySQL-Binärdistributionen, die von MySQL AB kompiliert wurden

@cindex Binärdistributionen

Als Service stellen wir bei MySQL AB einen Satz von Binärdistributionen von
MySQL zur Verfügung, die auf unserer Site kompiliert wurden oder auf Sites
von Kunden, die uns freundlicherweise Zugang zu Ihren Maschinen gewährt
haben.

Diese Distributionen werden mit @code{Skripts/make_binary_distribution}
erzeugt und mit folgenden Kompilern und Optionen konfiguriert:

@table @asis
@item SunOS 4.1.4 2 sun4c mit @code{gcc} 2.7.2.1
@code{CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-assembler}

@item SunOS 5.5.1 (und höher) sun4u mit @code{egcs} 1.0.3a oder 2.90.27 oder gcc 2.95.2 und neuer
@code{CC=gcc CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex --enable-assembler}

@item SunOS 5.6 i86pc mit @code{gcc} 2.8.1
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex}

@item Linux 2.0.33 i386 mit @code{pgcc} 2.90.29 (@code{egcs} 1.0.3a)
@code{CFLAGS="-O3 -mpentium -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentium -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --with-extra-charsets=complex}

@item Linux 2.2.x mit x686 mit @code{gcc} 2.95.2
@code{CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charset=complex}

@item SCO 3.2v5.0.4 i386 mit @code{gcc} 2.7-95q4
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}

@item AIX 2 4 mit @code{gcc} 2.7.2.2
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}

@item OSF1 V4.0 564 alpha mit @code{gcc} 2.8.1
@code{CC=gcc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-low-memory --with-extra-charsets=complex}

@item Irix 6.3 IP32 mit @code{gcc} 2.8.0
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}

@item BSDI BSD/OS 3.1 i386 mit @code{gcc} 2.7.2.1
@code{CC=gcc CXX=gcc CXXFLAGS=-O ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}

@item BSDI BSD/OS 2.1 i386 mit @code{gcc} 2.7.2
@code{CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql --with-extra-charsets=complex}
@end table

Wenn jemand optimalere Optionen für die obigen Konfigurationen hat, können
diese jederzeit der Entwickler-Mailing-Liste unter
@email{internals@@lists.mysql.com} mitgeteilt werden.

RPM-Distributionen von MySQL-Version 3.22 wurden durch Benutzer
beigesteuert. Ab Version 3.22 werden die RPMs von uns bei MySQL AB erzeugt.

Wenn Sie eine Debug-Version von MySQL kompilieren wollen, müssen Sie den
oben genannten Kompilierzeilen @code{--with-debug} oder
@code{--with-debug=full} hinzufügen und jegliche
@code{-fomit-frame-pointer}-Optionen entfernen.


@node Installing source, Post-installation, General Installation Issues, Installing
@c German node Installation der Quelldistribution
@section Installation der Quelldistribution

@cindex Installation, Quelldistribution
@cindex Quelldistribution, Installation
@cindex Installation, Überblick

Bevor Sie mit der Quellinstallation fortfahren, sehen Sie nach, ob eine
Binärdistribution für Ihre Plattform verfügbar ist, die so wie Sie wollen
funktioniert. Wir geben uns viel Mühe, die Binärdistributionen mit den
bestmöglichen Optionen zu bauen.

Sie benötigen folgende Werkzeuge, um MySQL aus der Quelldistribution zu bauen
und zu installieren:

@itemize @bullet
@item
GNU @code{gunzip}, um die Distribution zu entpacken.

@item
Ein vernünftiges @code{tar}, um die Distribution zu entpacken. Von GNU
@code{tar} ist bekannt, dass es funktioniert. Sun @code{tar} ist dafür
bekannt, dass es Probleme verursacht.

@item
Einen funktionierenden ANSI-C++-Kompiler. @code{gcc} >= 2.95.2, @code{egcs} >= 1.0.2
oder @code{egcs 2.91.66}, SGI C++ und SunPro C++ sind einige der Kompiler,
von denen bekannt ist, dass sie funktionieren. @code{libg++} wird nicht
benötigt, wenn Sie @code{gcc} benutzen. @code{gcc} 2.7.x hat einen Bug, der
es verunmöglicht, einige perfekt der vorgeschriebenen Form entsprechende
C++-Dateien zu kompilieren, zum Beispiel @file{sql/sql_base.cc}. Wenn Sie
nur @code{gcc} 2.7.x zur Verfügung haben, müssen Sie Ihren @code{gcc}
aktualisieren, um MySQL kompilieren zu können. @code{gcc} 2.8.1 ist
ebenfalls für Probleme auf einigen Plattformen bekannt, daher sollten Sie
auch diesen vermeiden, wenn Sie einen neueren Kompiler für diese Plattform
zur Verfügung haben.

@code{gcc} >= 2.95.2 wird für das Kompilieren von MySQL-Versionen 3.23.x
empfohlen.

@item
Ein gutes @code{make}-Programm. GNU @code{make} wird stets empfohlen und
ist manchmal erforderlich. Wenn Sie Probleme bekommen, empfehlen wir, es
mit GNU @code{make} 3.75 oder neuer zu versuchen.
@end itemize

Wenn Sie eine aktuelle Version von @strong{gcc} verwenden (aktuell genug,
um die @code{-fno-exceptions}-Option zu verstehen), ist es @strong{SEHR
WICHTIG}, dass Sie diese Option benutzen. Ansonsten könnte es sein, dass
Sie eine Binärdatei kompilieren, die zu zufälligen Zeitpunkten abstürzt.
Wir empfehlen zusätzlich, dass Sie @code{-felide-contructors} und
@code{-fno-rtti} zusammen mit @code{-fno-exceptions} benutzen. Im Zweifel
gehen Sie wie folgt vor:

@example

CFLAGS="-O3" CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static

@end example

Für die meisten Systeme werden Sie dadurch eine schnelle, stabile
Binärinstallation erhalten.

@c texi2html fails to split chapters if I use strong für all of this.
Wenn Sie Probleme bekommen, @strong{BITTE BENUTZEN SIE IMMER
@code{mysqlbug}} zum Fragenstellen die Liste
@email{mysql@@lists.mysql.com}. Selbst wenn das Problem kein Bug ist,
sammelt @code{mysqlbug} Systeminformationen, die anderen helfen werden, Ihr
Problem zu lösen. Wenn Sie @code{mysqlbug} nicht benutzen, verringern Sie
die Möglichkeit, eine Lösung Ihres Problems zu bekommen! @code{mysqlbug}
finden Sie im @file{scripts}-Verzeichnis, nachdem Sie die Distribution
entpackt haben. @xref{Bug reports}.



@menu
* Quick install::               
* Applying patches::            
* configure options::           
* Installing source tree::      
* Compilation problems::        
* MIT-pthreads::                
* Windows source build::        
@end menu

@node Quick install, Applying patches, Installing source, Installing source
@c German node Schnellinstallation
@subsection Schnellinstallation, Überblick

Die grundlegenden Befehle, die Sie ausführen müssen, um eine
MySQL-Quelldistribution zu installieren, sind:

@example
shell> groupadd mysql
shell> useradd -g mysql mysql
shell> gunzip < mysql-VERSION.tar.gz | tar -xvf -
shell> cd mysql-VERSION
shell> ./configure --prefix=/usr/local/mysql
shell> make
shell> make install
shell> scripts/mysql_install_db
shell> chown -R root  /usr/local/mysql
shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
@end example

@c German FIX added @samp before {#}
Wenn Sie Unterstützung für InnoDB-Tabellen haben wollen, sollten Sie die
Datei @code{/etc/my.cnf} editieren und die @samp{#}-Zeichen vor den Parametern
entfernen, der mit @code{innodb_...} beginnen. @xref{Option files}.
@xref{InnoDB start}.

Wenn Sie mit einem Quell-RPM anfangen, gehen Sie wie folgt vor:

@example
shell> rpm --rebuild MySQL-VERSION.src.rpm
@end example

Das erzeugt ein Binär-RPM, das Sie installieren können.

Sie können neue Benutzer hinzufügen, indem Sie das
@code{bin/mysql_setpermission}-Skript benutzen, falls Sie die @code{DBI}-
und @code{Msql-Mysql-modules}-Perl-Module installieren.

Eine detailliertere Beschreibung folgt.

Um eine Quelldistribution zu installieren, führen Sie die unten stehenden
Schritte aus und gehen dann weiter zu @ref{Post-installation}, um die
Schritte nach der Installation und ein paar Tests durchzuführen.

@enumerate
@item
Wählen Sie das Verzeichnis, in dem Sie die Distribution entpacken wollen,
und wechseln Sie dort hinein.

@item
Holen Sie sich eine Distributionsdatei von einer der Sites, die unter
@ref{Getting MySQL, , Wie man MySQL erhält} aufgelistet sind.

@item
Wenn Sie Berkeley-DB-Tabellen mit MySQL verwenden wollen, müssen Sie sich
eine gepatchte Version des Berkeley-DB-Quellcodes besorgen. Bitte lesen Sie
das Kapitel über Berkeley-DB-Tabellen, bevor Sie fortfahren.  @xref{BDB}.

MySQL-Quelldistributionen stehen als komprimierte @code{tar}-Archive zur
Verfügung und haben Namen wie @file{mysql-VERSION.tar.gz}, wobei
@code{VERSION} eine Zahl ist, wie @value{mysql_version}.

@item
Fügen Sie einen Benutzer (User) und eine Gruppe (Group) hinzu, unter dem /
der @code{mysqld} laufen soll:

@example
shell> groupadd mysql
shell> useradd -g mysql mysql
@end example

Diese Befehle fügen den Benutzer @code{mysql} und die Gruppe @code{mysql}
hinzu. Die Syntax für @code{useradd} und @code{groupadd} kann sich auf
unterschiedlichen Unix-Systemen geringfügig unterscheiden. Die Befehle
können @code{adduser} und @code{addgroup} heißen. Wenn Sie wollen, können
Sie Benutzer und Gruppe auch anders nennen als @code{mysql}.

@item
Entpacken Sie die Distribution ins aktuelle Verzeichnis:
@example
shell> gunzip < /pfad/zu/mysql-VERSION.tar.gz | tar xvf -
@end example

Dieser Befehl erzeugt ein Verzeichnis namens @file{mysql-VERSION}.

@item
Wechseln Sie in das oberste Verzeichnis der entpackten Distribution:

@example
shell> cd mysql-VERSION
@end example

Beachten Sie, dass Sie aktuell MySQL aus diesem obersten Verzeichnis
konfigurieren und bauen müssen. Sie können MySQL nicht in ein anderes
Verzeichnis bauen.

@item
Konfigurieren Sie das Release und kompilieren Sie alles:

@example
shell> ./configure --prefix=/usr/local/mysql
shell> make
@end example

Wenn Sie @code{configure} laufen lassen, können Sie dabei einige Optionen
angeben. Geben Sie @code{./configure --help} ein, um eine Liste von
Optionen zu erhalten. @ref{configure options, , @code{configure}-Optionen}
erörtert einige der nützlicheren Optionen.

Wenn @code{configure} fehlschlägt und Sie sich wegen Hilfe an
@email{mysql@@lists.mysql.com} wenden, geben Sie bitte alle Zeilen aus
@file{config.log} an, von denen Sie annehmen, dass sie bei der
Problembehebung hilfreich sein könnten. Fügen Sie auch die letzten Zeilen
der Ausgabe von @code{configure} hinzu, wenn @code{configure} abbricht.
Schicken Sie den Bug-Bericht ein, indem Sie das @code{mysqlbug}-Skript
benutzen. @xref{Bug reports}.

Wenn das Kompilieren fehlschlägt, sehen Sie unter
@ref{Compilation problems} nach, was bei einer Reihe geläufiger Probleme
hilft.

@item
Installieren Sie alles:

@example
shell> make install
@end example

Eventuell müssen Sie diesen Befehl als @code{root} ausführen.

@item
Erzeugen Sie die MySQL-Berechtigungstabellen (Grant Tables, nur notwendig,
wenn Sie MySQL noch nie vorher installiert haben):

@example
shell> scripts/mysql_install_db
@end example

Beachten Sie, dass bei MySQL-Versionen vor Version 3.22.10 der MySQL-Server
startet, wenn Sie @code{mysql_install_db} laufen lassen. Das gilt für
neuere Versionen nicht mehr!

@item
Ändern Sie den Besitzer der Binärdateien zu @code{root} und den Besitzer
des Daten-Verzeichnisses zu dem Benutzer, unter dem Sie @code{mysqld} laufen
lassen wollen:

@example
shell> chown -R root  /usr/local/mysql
shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql
@end example

Der erste Befehl ändert die @code{owner}-Attribute der Dateien auf den
Benutzer @code{root}, der zweite ändert die @code{owner}-Attribute des
Daten-Verzeichnisses auf den Benutzer @code{mysql} und der dritte ändert die
@code{group}-Attribute auf die Gruppe @code{mysql}.

@item
Wenn Sie die Unterstützung für die Perl-@code{DBI}/@code{DBD}-Schnittstelle
hinzufügen wollen, sehen Sie unter @ref{Perl} nach.

@item
Wenn Sie wollen, dass MySQL automatisch startet, wenn Sie Ihre Maschine
hoch fahren, kopieren Sie @code{support-files/mysql.server} an die Stelle,
wo Ihr System seine Startdateien hat. Weitere Informationen finden Sie im
@code{support-files/mysql.server}-Skript selbst sowie unter
@ref{Automatic start}.
@end enumerate

Nachdem alles installiert wurde, sollten Sie Ihre Distribution
initialisieren und testen:

@example
shell> /usr/local/mysql/bin/safe_mysqld --user=mysql &
@end example

Wenn dieser Befehl sofort mit @code{mysqld daemon ended} fehlschlägt,
finden Sie einige Informationen dazu in der Datei
@file{mysql-Daten-Verzeichnis/'hostname'.err}. Der wahrscheinliche Grund ist
der, dass bereits ein anderer @code{mysqld}-Server läuft. @xref{Multiple servers}.

@xref{Post-installation}.


@node Applying patches, configure options, Quick install, Installing source
@c German node Patches anwenden
@subsection Wie man Patches anwendet

@cindex Patches, anwenden
@cindex Anwenden, Patches

Manchmal erscheinen Patches auf der Mailing-Liste oder werden auf
@uref{http://www.mysql.com/Downloads/Patches, Patches-Bereich} auf der
MySQL-Website eingestellt.

Um einen Patch aus der Mailing-Liste anzuwenden, speichern Sie die
Nachricht, in der der Patch enthalten ist, in eine Datei. Wechseln Sie dann
ins oberste Verzeichnis Ihres MySQL-Source-Trees und geben Sie folgende
Befehle ein:

@example
shell> patch -p1 < patch-datei-name
shell> rm config.cache
shell> make clean
@end example

Patches von der FTP-Site werden als Klartextdateien (Plain Text) oder als
mit @code{gzip} komprimierte Dateien distribuiert. Ein Klartext-Patch
wenden Sie genau so an, wie oben für die Patches von der Mailing-Liste
beschrieben. Um ein komprimiertes Patch anzuwenden, wechseln Sie ins
oberste Verzeichnis Ihres MySQL-Source-Trees und geben Sie folgende Befehle
ein:

@example
shell> gunzip < patch-datei-name.gz | patch -p1
shell> rm config.cache
shell> make clean
@end example

Nachdem Sie einen Patch angewendet haben, folgen Sie den Anweisungen für
eine normale Installation vom Quellcode, indem Sie mit dem Schritt
@code{./configure} anfangen. Nach dem Schritt @code{make install}, starten
Sie den MySQL-Server neu.

Es kann sein, dass Sie jeden laufenden Server anhalten müssen, bevor Sie
@code{make install} laufen lassen können. (Das machen Sie mit
@code{mysqladmin shutdown}.) Einige Systeme lassen es nicht zu, dass eine
neue Programmversion installiert wird, wenn diese eine Version ersetzt, die
momentan ausgeführt wird.


@node configure options, Installing source tree, Applying patches, Installing source
@c German node Optionen konfigurieren
@subsection Typische @code{configure}-Optionen

@findex without-server-Option
@cindex @code{configure}-Skript
@cindex Optionen, configure
@cindex Konfigurationsoptionen
@cindex Log-Dateien
@cindex Dateien, Log

Das @code{configure}-Skript gibt Ihnen in großem Umfang Kontrolle über die
Konfigurationsmöglichkeiten Ihrer MySQL-Distribution. Typischerweise machen
Sie das unter Verwendung der Optionen auf der
@code{configure}-Kommandozeile. Sie können ausserdem @code{configure}
beeinflussen, indem Sie bestimmte Umgebungsvariablen benutzen.
@xref{Environment variables}. Um eine Liste der Optionen zu erhalten, die
@code{configure} unterstützt, geben Sie folgendes ein:

@example
shell> ./configure --help
@end example

Einige der gebräuchlicheren @code{configure}-Optionen sind im Folgenden
beschrieben:

@itemize @bullet
@item
Um nur die MySQL-Client Bibliotheken und Client-Programme und nicht den
Server zu kompilieren, benutzen Sie die @code{--ohne-server}-Option:

@example
shell> ./configure --without-server
@end example

@c FIX incorrect..

Wenn Sie keinen C++-Kompiler haben, können Sie @code{mysql} nicht
kompilieren (MySQL ist das einzige Client-Programm, das C++ erfordert). In
diesem Fall können Sie den Code in @code{configure} entfernen, der auf den
C++-Kompiler testet, und dann @code{./configure} mit der
@code{--without-server}-Option eingeben. Dieser Kompilierschritt wird nach
wie vor versuchen, @code{mysql} zu bauen, aber Sie können alle Warnungen zu
@file{mysql.cc} ignorieren. (Wenn @code{make} anhält, versuchen Sie
@code{make -k}, um ihm mitzuteilen, dass es mit dem Rest des Builds
fortfahren soll, auch wenn Fehler auftreten.)

@item
Wenn Sie nicht wollen, dass Ihre Log-Dateien und Datenbankverzeichnisse
unter @file{/usr/local/var} liegen, benutzen Sie ein
@code{configure}-Kommando wie folgendes:

@example
shell> ./configure --prefix=/usr/local/mysql
shell> ./configure --prefix=/usr/local \
           --localstatedir=/usr/local/mysql/data
@end example

Der erste Befehl ändert das Installationspräfix, so dass alles unter
@file{/usr/local/mysql} statt unter @file{/usr/local} installiert wird. Der
zweite Befehl bewahrt das vorgabemäßige Installationspräfix, aber
überschreibt die vorgabemäßige Stelle für Datenbankverzeichnisse
(normalerweise @file{/usr/local/var}) und ändert sie zu
@code{/usr/local/mysql/data}.

@cindex Speicherort des Sockets ändern
@cindex Socket-Speicherort, ändern
@cindex mysql.sock, Änderung des Speicherorts
@item

Wenn Sie Unix benutzen und wollen, dass der MySQL-Socket an anderer Stelle
liegt als vorgabemäßig (normalerweise im Verzeichnis @file{/tmp} oder
@file{/var/run}), benutzen Sie ein @code{configure}-Kommando wie folgendes:

@example
shell> ./configure --with-unix-socket-path=/usr/local/mysql/tmp/mysql.sock
@end example

Beachten Sie, dass die angegebene Datei mit einem absoluten Pfadnamen
angegeben werden muss! Sie können den Speicherort von @file{mysql.sock}
auch später noch ändern, indem Sie die MySQL Optionsdateien benutzen.
@xref{Problems with mysql.sock}.

@cindex Kompilieren, statisch
@cindex Statisch, Kompilieren
@item
Wenn Sie statisch gelinkte Programme kompilieren wollen (um zum Beispiel
eine Binärdistribution zu machen, mehr Geschwindigkeit zu erhalten oder
Probleme mit RedHat-Linux-Distributionen zu umgehen (Workaround)), geben
Sie @code{configure} wie folgt ein:

@example
shell> ./configure --with-client-ldflags=-all-static \
           --with-mysqld-ldflags=-all-static
@end example



@tindex @code{CC} Umgebungsvariable
@tindex Umgebungsvariable, @code{CC}
@tindex @code{CXX} Umgebungsvariable
@tindex Umgebungsvariable, @code{CXX}
@cindex @code{gcc}
@cindex C++-Kompiler, @code{gcc}
@cindex Kompiler, C++ @code{gcc}
@item
Wenn Sie @code{gcc} benutzen und @code{libg++} oder @code{libstdc++} nicht
installiert haben, können Sie @code{configure} mitteilen, @code{gcc} als
Ihren C++-Kompiler zu benutzen:

@example
shell> CC=gcc CXX=gcc ./configure
@end example

Wenn Sie @code{gcc} als C++-Kompiler benutzen, versucht dieser nicht,
@code{libg++} oder @code{libstdc++} zu linken.

Hier sind einige gebräuchliche Umgebungsvariablen, die man in Abhängigkeit
vom verwendeten Kompiler setzen kann:

@tindex CXXFLAGS Umgebungsvariable
@tindex Umgebungsvariable, CXXFLAGS
@multitable @columnfractions .20 .80
@item gcc 2.7.2.1 @tab
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors"
@item egcs 1.0.3a @tab
CC=gcc CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti"
@item gcc 2.95.2 @tab
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti"
@item pgcc 2.90.29 oder newer @tab
CFLAGS="-O3 -mpentiumpro -mstack-align-double" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -mstack-align-double -felide-constructors -fno-exceptions -fno-rtti"
@end multitable

In den meisten Fällen erhalten Sie eine ziemlich optimale MySQL-Binärdatei,
indem Sie die Optionen von weiter oben nutzen und die folgenden Optionen
zur Konfigurationszeile hinzufügen:

@example
--prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
@end example

Die komplette Konfigurationszeile würde also etwa wie folgt aussehen (für
alle aktuellen gcc-Versionen):

@example
CFLAGS="-O3 -mpentiumpro" CXX=gcc CXXFLAGS="-O3 -mpentiumpro -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static
@end example

Die Binärdistributionen, die wir auf der MySQL-Website unter
@uref{http://www.mysql.com} zur Verfügung stellen, sind allesamt mit voller
Optimierung kompiliert und sollten daher für die meisten Benutzer perfekt
sein. @xref{MySQL binaries}. Einiges können Sie noch fein justieren, um
noch schnellere Binärdistributionen zu erhalten, aber das ist nur etwas für
fortgeschrittene Benutzer.  @xref{Compile and link options}.

Wenn der Build fehlschlägt und Fehler produziert, die aussagen, dass Ihr
Kompiler oder Linker nicht in der Lage ist, die gemeinsam benutzte
(shared) Bibliothek @file{libmysqlclient.so.#} (@samp{#} ist eine
Versionsnummer) zu erzeugen, können Sie dieses Problem umgehen, indem Sie
die @code{--disable-shared}-Option von @code{configure} benutzen. In diesem
Fall baut @code{configure} keine gemeinsam benutzte
@code{libmysqlclient.so.#}-Bibliothek.

@cindex Vorgabewerte, Unterdrückung
@cindex Unterdrückung, Vorgabewerte
@item
Sie können MySQL so konfigurieren, dass keine @code{DEFAULT}-Spaltenwerte
für Nicht-@code{NULL}-Spalten benutzt werden (also Spalten, bei denen nicht
zulässig ist, dass sie @code{NULL} sind). Das führt dazu, dass
@code{INSERT}-Statements einen Fehler erzeugen, ausser wenn ausdrücklich
Werte für Spalten angegeben werden, die einen Nicht-@code{NULL}-Werte
verlangen. Um die Benutzung von Vorgabewerten zu unterdrücken, geben Sie
@code{configure} wie folgt ein:

@tindex CXXFLAGS Umgebungsvariable
@tindex Umgebungsvariable, CXXFLAGS
@example
shell> CXXFLAGS=-DDONT_USE_DEFAULT_FIELDS ./configure
@end example

@cindex Zeichensätze
@findex configure-Option, --with-charset
@findex configure-Option, --with-extra-charset
@item
Als Vorgabe benutzt MySQL den Zeichensatz ISO-8859-1 (Latin1). Um diesen
Vorgabesatz zu ändern, benutzen Sie die @code{--with-charset}-Option:
@example
shell> ./configure --with-charset=CHARSET
@end example
@code{CHARSET} kann einer der folgenden sein: @code{big5}, @code{cp1251}, @code{cp1257},
@code{czech}, @code{danish}, @code{dec8}, @code{dos}, @code{euc_kr},
@code{gb2312}, @code{gbk}, @code{german1}, @code{hebrew}, @code{hp8},
@code{hungarian}, @code{koi8_ru}, @code{koi8_ukr}, @code{latin1},
@code{latin2}, @code{sjis}, @code{swe7}, @code{tis620}, @code{ujis},
@code{usa7} oder @code{win1251ukr}.
@xref{Character sets}.

Wenn Sie Zeichen zwischen Server und Client konvertieren wollen, sollten
Sie sich den @code{SET OPTION CHARACTER SET}-Befehl ansehen.
@xref{SET OPTION, , @code{SET OPTION}}.

@cindex @code{myisamchk}
@strong{Achtung:} Wenn Sie Zeichensätze ändern, nachdem Sie irgend welche
Tabellen angelegt haben, müssen Sie @code{myisamchk -r -q} über jede
Tabelle laufen lassen, denn ansonsten könnten Ihre Indexe falsch sortiert
werden. (Das kann passieren, wenn Sie MySQL installieren, ein paar Tabellen
erzeugen und danach MySQL rekonfigurieren, so dass es einen anderen
Zeichensatz benutzt, und dann neu installieren.)

Mit der Option @code{--with-extra-charset=LIST} können Sie zusätzliche
Zeichensätze definieren, die in den Server einkompiliert werden sollen.

Hierbei ist @code{LIST} entweder eine Liste eines Zeichensatzes, die durch
Leerzeichen getrennt ist, oder @code{complex}, um alle Zeichen
einzuschließen, die nicht dynamisch geladen werden können, oder
@code{all}, um alle Zeichensätze in die Binärdateien einzuschließen.

@item
Um MySQL mit Debug-Code zu konfigurieren, benutzen Sie die
@code{--with-debug}-Option:
@example
shell> ./configure --with-debug
@end example
Das bewirkt, dass eine sichere Speicherzuweisung (Memory Allocator)
eingeschlossen wird, die einige Fehler finden kann und die Ausgaben
liefert, was passiert ist. @xref{Debugging server}.

@item
Wenn Ihre Client-Programme Threads benutzen, müssen Sie zusätzlich eine
Thread-sichere Version der MySQL-Client-Bibliothek mit der
@code{--enable-Thread-safe-client}-configure-Option kompilieren. Hierdurch
wird eine @code{libmysqlclient_r}-Bibliothek angelegt, mit der Sie Ihre
threaded Applikationen linken können. @xref{Threaded clients}.

@item
Optionen, die zu bestimmten Systemen gehören, finden sich im
systemspezifischen Abschnitt dieses Handbuchs. @xref{Which OS, , Betriebssystemspezifische Anmerkungen}.
@end itemize


@node Installing source tree, Compilation problems, configure options, Installing source
@c German node Installation vom Entwicklungs-Source-Tree
@subsection Installation vom Entwicklungs-Source-Tree

@cindex Entwicklungs-Source-Tree
@cindex BitKeeper-Tree
@cindex CVS-Tree

@strong{VORSICHT:} Sie sollten diesen Abschnitt nur lesen, wenn Sie daran
interessiert sind, uns beim Testen von neuem Code zu helfen. Wenn Sie nur
wollen, dass MySQL auf Ihrem System läuft, sollten Sie eine
Standard-Distribution wählen (entweder eine Quell- oder eine
Binärdistribution).

Um unseren aktuellsten Entwicklungs-Source-Tree zu bekommen, folgen Sie
diesen Anweisungen:

@enumerate
@item
Laden Sie @strong{BitKeeper} von
@uref{http://www.bitmover.com/cgi-bin/download.cgi} herunter. Sie benötigen
@strong{Bitkeeper} 2.0 oder neuer, um auf unser Repository zuzugreifen.

@item
Folgen Sie den Anweisungen, um BitKeeper zu installieren.

@item
Nachdem @strong{BitKeeper} installiert ist, benutzen Sie diesen Befehl, um
den MySQL-3.23-Branch zu klonen:

@example
shell> bk clone bk://work.mysql.com:7000 mysql
@end example

Um den 4.0-Branch zu klonen, benutzen Sie statt dessen diesen Befehl:

@example
shell> bk clone bk://work.mysql.com:7001 mysql-4.0
@end example

Das erstmalige Herunterladen des Source-Trees kann eine Weile dauern,
abhängig von Ihrer Verbindungsgeschwindigkeit. Bitte Geduld.

@item
Sie brauchen GNU @code{autoconf}, @code{automake}, @code{libtool} und
@code{m4}, um die nächsten Befehle auszuführen.
Wenn Sie in diesem Stadium seltsame Fehler erhalten, überprüfen Sie bitte,
ob Sie wirklich @code{libtool} installiert haben!

@example
shell> cd mysql
shell> bk -r edit
shell> aclocal; autoheader; autoconf;  automake;
shell> ./configure  # Geben Sie hier Ihre Lieblingsoptionen an
shell> make
@end example

Eine Sammlung unserer Standard-configure-Skripts befindet sich im
@file{BUILD/} Unterverzeichnis. Wenn Sie faul sind, können Sie
@file{BUILD/compile-pentium-debug} benutzen. Um für unterschiedliche
Architekturen zu kompilieren, ändern Sie das Skript ab und entfernen die
Flags, die Pentium-spezifisch sind.

@item
Wenn der Build fertig ist, lassen Sie @code{make install} laufen. Seien Sie
damit vorsichtig auf Produktionsmaschinen, denn dieser Befehl kann Ihre
Live-Release-Installation überschreiben! Wenn Sie eine weitere Installation
von MySQL haben, empfehlen wir, dass Sie @code{./configure} mit anderen
Werten für die @code{prefix}-, @code{tcp-port}- und
@code{unix-socket-path}-Optionen ausführen als die, die für Ihren
Produktionsserver benutzt werden.

@item
Spielen Sie reichlich mit Ihrer neuen Installation herum und versuchen Sie,
die neuen Features zum Absturz zu bringen. Fangen Sie an, indem Sie
@code{make test} laufen lassen. @xref{MySQL-Test-Suite}.

@item
Wenn Sie bis zum @code{make}-Stadium gekommen sind und die Distribution
sich nicht kompilieren läßt, berichten Sie das bitte an
@email{bugs@@lists.mysql.com}. Wenn Sie die letzten Versionen der
erforderlichen GNU-Werkzeuge installiert haben und sie abstürzen, wenn Sie
versuchen, Ihre Konfigurationsdateien zu verarbeiten, berichten Sie das
bitte ebenfalls. Wenn Sie jedoch @code{aclocal} und einen @code{Befehl
nicht gefunden}-Fehler erhalten, berichten Sie diesen nicht. Stellen Sie
statt dessen sicher, dass alle notwendigen Werkzeuge installiert sind und dass
Ihre @code{PATH}-Variable korrekt gesetzt ist, damit Ihre Shell diese
finden kann.

@item
Nach der erstmaligen @code{bk clone}-Operation, um den Source-Tree zu
erhalten, sollten Sie in regelmäßigen Abständen @code{bk pull} laufen
lassen, um Aktualisierungen zu erhalten.

@item
Sie erhalten die Änderungen-Geschichte (Change History) des Trees mit allen
Diffs, indem Sie @code{bk sccstool} benutzen. Wenn Sie seltsame Diffs sehen
oder Code, zu dem Sie Fragen haben, zögern Sie nicht, uns eine E-Mail an
@email{internals@@lists.mysql.com} zu schicken. Auch wenn Sie meinen, eine
bessere Idee zu haben, wie etwas gemacht werden sollte, schicken Sie uns
eine E-Mail an dieselbe Adresse, mit einem Patch. @code{bk diffs} erzeugt
ein Patch für Sie, nachdem Sie Änderungen am Quellcode durchgeführt haben.
Wenn Sie keine Zeit haben, Ihre Idee zu kodieren, schicken Sie einfach eine
Beschreibung.

@item
@strong{BitKeeper} hat ein nettes Hilfe-Dienstprogramm, auf das Sie über @code{bk
helptool} zugreifen können.

@end enumerate


@node Compilation problems, MIT-pthreads, Installing source tree, Installing source
@c German node Kompilierungsprobleme
@subsection Probleme beim Kompilieren?

@cindex Kompilieren, Probleme
@cindex Probleme, Kompilieren
@cindex Rekonfigurieren
@cindex @code{config.cache}-Datei
@cindex Dateien, @code{config.cache}

Alle MySQL-Programme lassen sich sauber ohne Warnungen auf Solaris mit
@code{gcc} kompilieren. Auf anderen Systemen können Warnungen wegen
Unterschieden in System-Include-Dateien auftreten. Siehe @ref{MIT-pthreads}
wegen Warnungen, die auftreten können, wenn Sie MIT-pThreads verwenden.
Wegen anderer Probleme sehen Sie bitte in der unten stehenden Liste nach.

Die Lösung für viele Probleme beinhaltet Rekonfigurieren. Wenn Sie
rekonfigurieren müssen, beachten Sie Folgendes:

@cindex @code{configure} nach dem ersten Aufruf laufen lassen
@cindex @code{configure}, laufen lassen nach dem ersten Aufruf
@cindex Rekonfigurieren
@cindex config.cache
@itemize @bullet
@item
Wenn @code{configure} laufen gelassen wird, nachdem es schon einmal lief,
benutzt es möglicherweise Informationen, die bei vorherigen Aufrufen
gesammelt wurden. Diese Information wird in der Datei @file{config.cache}
gespeichert. Wenn @code{configure} startet, sucht es diese Datei und liest
ihren Inhalt, wenn sie existiert, unter der Annahme, dass diese Information
immer noch stimmt. Diese Annahme ist falsch, wenn Sie rekonfigurieren.

@item
Immer, wenn Sie @code{configure} laufen lassen, müssen Sie auch @code{make}
laufen lassen, um erneut zu kompilieren. Sie werden jedoch einige alte
Objektdateien vorheriger Builds entfernen wollen, denn diese wurden mit
anderen Konfigurationsoptionen kompiliert.
@end itemize

Um zu verhindern, dass alte Konfigurationsinformationen oder Objektdateien
benutzt werden, geben Sie vor dem erneuten Aufruf von @code{configure}
folgende Befehle ein:

@example
shell> rm config.cache
shell> make clean
@end example

Alternativ können Sie auch @code{make distclean} laufen lassen.

Die unten stehende Liste beschreibt einige der Probleme, die beim
Kompilieren von MySQL am häufigsten auftreten:

@itemize @bullet
@item
@cindex @code{cc1plus}-Probleme
@cindex @code{fatal signal 11}
@cindex @code{sql_yacc.cc}-Probleme
@cindex Interne Kompiler-Fehler
@cindex Virtueller Speicher, Probleme beim Kompilieren
@cindex configure-Option, --with-low-memory
Wenn Sie Probleme beim Kompilieren von @file{sql_yacc.cc} erhalten, die den
unten gezeigten ähneln, haben Sie wahrscheinlich keinen Arbeitsspeicher
oder Swap-Platz (Auslagerungsdatei) mehr.

@example
Internal compiler error: Programm cc1plus got fatal signal 11
  oder
Out of virtual memory
  oder
Virtual memory exhausted
@end example

Das Problem liegt darin, dass @code{gcc} riesige Mengen von Arbeitsspeicher
benötigt, um @file{sql_yacc.cc} mit Inline-Funktionen zu kompilieren.
Versuchen Sie, @code{configure} mit der @code{--with-low-memory}-Option
auszuführen:

@example
shell> ./configure --with-low-memory
@end example

Diese Option veranlasst, dass @code{-fno-inline} zur Kompilierzeile
hinzugefügt wird, wenn Sie @code{gcc} benutzen, bzw. @code{-O0}, wenn Sie
etwas anderes benutzen. Sie sollten die @code{--with-low-memory}-Option
selbst dann benutzen, wenn Sie glauben, so viel Arbeitsspeicher und
Swap-Platz zu haben, dass Ihnen diese unmöglich ausgehen können. Das
Problem wurde selbst auf Systemen mit großzügiger Hardware-Ausstattung
beobachtet, und die @code{--with-low-memory}-Option behebt es
üblicherweise.

@item
Vorgabemäßig sucht @code{configure} @code{c++} als Kompiler-Namen aus und
GNU @code{c++} linkt mit @code{-lg++}. Wenn Sie @code{gcc} benutzen, kann
dieses Verhalten Probleme bei Konfigurationen wie dieser verursachen:

@cindex C++-Kompiler kann keine ausführbaren Dateien (Executables) erzeugen
@example
configure: error: installation oder configuration problem:
c++ compiler cannot create executables.
@end example

@tindex CXX-Umgebungsvariable
@tindex Umgebungsvariable, CXX
Eventuell stoßen Sie beim Kompilieren auch auf Probleme, die mit
@code{g++}, @code{libg++} oder @code{libstdc++} zu tun haben.

Eine Ursache dieser Probleme liegt darin, dass Sie kein @code{g++} haben
dürfen, oder Sie dürfen @code{g++} haben, aber nicht @code{libg++} oder
@code{libstdc++}. Schauen Sie in die @file{config.log}-Datei! Sie sollten
die genaue Ursache enthalten, warum Ihr C++-Kompiler nicht funktioniert! Um
dieses Problem zu umgehen, können Sie @code{gcc} als Ihren C++-Kompiler
benutzen. Versuchen Sie, die Umgebungsvariable @code{CXX} auf @code{"gcc
-O3"} zu setzen. Beispiel:

@tindex CXX-Umgebungsvariable
@tindex Umgebungsvariablen, CXX
@example
shell> CXX="gcc -O3" ./configure
@end example

Das funktioniert, weil @code{gcc} C++-Quellen genau so gut wie @code{g++}
kompiliert, aber vorgabemäßig weder @code{libg++} noch @code{libstdc++}
linkt.

Eine andere Möglichkeit, das Problem zu beheben, besteht natürlich darin,
@code{g++}, @code{libg++} und @code{libstdc++} zu installieren.

@item
Wenn Ihr Kompilieren mit Fehlern wie dem folgenden fehlschlägt, müssen Sie
Ihre Version von @code{make} auf GNU @code{make} aktualisieren:

@example
making all in mit-pThreads
make: Fatal error in reader: Makefile, line 18:
Badly formed macro assignment
  oder
make:Datei `Makefile' line 18: Must be a separator (:
  oder
pThread.h: No such file or directory
@end example

@cindex Solaris-Troubleshooting
@cindex FreeBSD-Troubleshooting
@cindex Troubleshooting, Solaris
@cindex Troubleshooting, FreeBSD
Von Solaris und FreeBSD ist bekannt, dass sie problembehaftete
@code{make}-Programme haben.

GNU @code{make} Version 3.75 funktioniert bekanntermaßen.

@tindex CC-Umgebungsvariable
@tindex Umgebungsvariable, CC
@tindex CXX-Umgebungsvariable
@tindex Umgebungsvariable, CXX
@tindex CFLAGS-Umgebungsvariable
@tindex Umgebungsvariable, CFLAGS
@tindex CXXFLAGS-Umgebungsvariable
@tindex Umgebungsvariable, CXXFLAGS
@item
Wenn Sie Flags definieren wollen, die von Ihrem C- oder C++-Kompiler
benutzt werden, fügen Sie die Flags den @code{CFLAGS}- und
@code{CXXFLAGS}-Umgebungsvariablen hinzu. Sie können auf diese Weise auch
die Kompilernamen festlegen, indem Sie @code{CC} und @code{CXX} benutzen.
Beispiel:

@example
shell> CC=gcc
shell> CFLAGS=-O3
shell> CXX=gcc
shell> CXXFLAGS=-O3
shell> export CC CFLAGS CXX CXXFLAGS
@end example

Siehe @ref{MySQL binaries}: Eine Liste von Flag-Definitionen, die sich
auf verschiedenen Systemen als nützlich erwiesen haben.

@item
Wenn Sie einen Fehler wie den folgenden erhalten, müssen Sie Ihren
@code{gcc}-Kompiler aktualisieren:

@example
client/libmysql.c:273: parse error before `__attribute__'
@end example

@code{gcc} 2.8.1 funktioniert bekanntermaßen, aber wir empfehlen statt
dessen @code{gcc} 2.95.2 oder @code{egcs} 1.0.3a.

@item
Wenn Sie Fehler wie die unten stehenden erhalten, wenn Sie @code{mysqld}
kompilieren, hat @code{configure} den Typ des letzten Arguments für
@code{accept()}, @code{getsockname()} oder @code{getpeername()} nicht
korrekt erkannt:

@example
cxx: Error: mysqld.cc, line 645: In this statement, the referenced
     type of the pointer value "&length" is "unsigned long", which
     is not compatible with "int".
new_sock = accept(sock, (struct sockaddr *)&cAddr, &length);
@end example

Um das zu beheben, editieren Sie die @file{config.h}-Datei (die von
@code{configure} angelegt wird). Suchen Sie nach folgenden Zeilen:

@example
/* Define as the base type of the last arg to accept */
#define SOCKET_SIZE_TYPE XXX
@end example

Ändern Sie @code{XXX} zu @code{size_t} oder @code{int}, abhängig von Ihrem
Betriebssystem. (Beachten Sie, dass Sie das jedes Mal tun müssen, wenn Sie
@code{configure} laufen lassen, weil @code{configure} die Datei
@file{config.h} neu erzeugt.)

@item
Die @file{sql_yacc.cc}-Datei wird von @file{sql_yacc.yy} erzeugt.
Normalerweise muss der Build-Prozess keine @file{sql_yacc.cc} erzeugen,
weil MySQL schon mit einer fertig erzeugten Kopie daher kommt. Wenn Sie sie
jedoch neu erzeugen müssen, könnten Sie folgenden Fehler erhalten:

@example
"sql_yacc.yy", line xxx fatal: default action causes potential...
@end example

Das ist ein Indiz dafür, dass Ihre Version von @code{yacc} fehlerhaft ist.
Sie müssen statt dessen wahrscheinlich @code{bison} (die GNU-Version von
@code{yacc}) installieren und benutzen.

@item
Wenn Sie @code{mysqld} oder einen MySQL-Client debuggen wollen, lassen Sie
@code{configure} mit der @code{--with-debug}-Option laufen. Kompilieren Sie
danach neu und linken Sie Ihre Clients mit der neuen Client-Bibliothek.
@xref{Debugging client}.
@end itemize

@node MIT-pthreads, Windows source build, Compilation problems, Installing source
@c German node MIT-pThreads
@subsection Anmerkungen zu MIT-pThreads

@cindex MIT-pThreads
@cindex Thread-Unterstützung, nicht-native

Dieser Abschnitt beschreibt einige der Themen im Zusammenhang mit MIT-pThreads.

Beachten Sie, dass Sie auf Linux KEINE MIT-pThreads benutzen, sondern statt
dessen LinuxThreads installieren sollten!
@xref{Linux}.

Wenn Ihr System keine native Thread-Unterstützung bietet, müssen Sie MySQL
unter Verwendung des MIT-pThread-Pakets bauen. Das betrifft ältere
FreeBSD-Systeme, SunOS 4.x, Solaris 2.4 und früher und einige andere.
@xref{Which OS}.

@itemize @bullet
@item
Auf den meisten Systemen können Sie die Benutzung von erzwingen, indem Sie
@code{configure} mit der @code{--with-mit-Threads}-Option laufen lassen:

@example
shell> ./configure --with-mit-threads
@end example

Wenn Sie MIT-pThreads benutzen, wird das Bauen (Building) in ein
Nicht-Quellcode-Verzeichnis nicht unterstützt, weil wir die Änderungen an
diesem Code minimal halten wollen.

@item
Die Überprüfungen, die festlegen, ob MIT-pThreads benutzt werden sollten
oder nicht, finden nur in dem Teil des Konfigurationsprozesses statt, der
mit dem Server-Code zu tun hat. Wenn Sie die Distribution mit
@code{--without-server} konfigurieren, um nicht den Client-Code zu bauen,
wissen die Clients nicht, ob sie MIT-pThreads benutzen sollen oder nicht
und werden vorgabemäßig Unix-Socket-Verbindungen benutzen. Weil
Unix-Sockets unter MIT-pThreads nicht laufen, heißt das, dass Sie
@code{-h} oder @code{--host} benutzen müssen, wenn Sie Client-Programme
laufen lassen.

@item
Wenn MySQL so kompiliert wird, dass es MIT-pThreads benutzt, wird
System-Sperren (System Locking) vorgabemäßig aus Performance-Gründen
ausgeschaltet. Mit der @code{--use-locking}-Option können Sie dem Server
mitteilen, System-Sperren zu benutzen.

@item
Manchmal schlägt der pThread-@code{bind()}-Befehl fehl und bindet nicht an
ein Socket, ohne jede Fehlermeldung (zumindest auf Solaris). Als Ergebnis
schlagen alle Verbindungen zum Server fehl. Beispiel:

@example
shell> mysqladmin version
mysqladmin: connect to server at '' failed;
error: 'Can't connect to mysql server on localhost (146)'
@end example

Die Lösung besteht darin, den @code{mysqld}-Server zu killen und neu zu
starten. Uns ist das nur dann passiert, wenn wir den Server gezwungen
haben, herunter zu fahren und sofort danach einen Neustart durchgeführt
haben.

@item
Bei MIT-pThreads läßt sich der @code{sleep()}-Systemaufruf nicht mit
@code{SIGINT} (break) unterbrechen. Das merken Sie nur, wenn Sie
@code{mysqladmin --sleep} ausführen. Sie müssen dann warten, bis der
@code{sleep()}-Aufruf beendet wurde, bevor die Unterbrechungsanforderung
(Interrupt) bedient wird und der Prozess anhält.

@item
Wenn Sie linken, erhalten Sie möglicherweise Warnmeldungen wie diese
(zumindest auf Solaris). Sie können sie ignorieren:

@example
ld: warning: symbol `_iob' hat differing sizes:
    (file /my/local/pThreads/lib/libpThread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
    /my/local/pThreads/lib/libpThread.a(findfp.o) definition taken
ld: warning: symbol `__iob' hat differing sizes:
    (file /my/local/pThreads/lib/libpThread.a(findfp.o) value=0x4;
file /usr/lib/libc.so value=0x140);
    /my/local/pThreads/lib/libpThread.a(findfp.o) definition taken
@end example

@item
Einige weitere Warnungen können ebenfalls ignoriert werden:

@example
implicit declaration of function `int strtoll(...)'
implicit declaration of function `int strtoul(...)'
@end example

@item
Wir haben es bislang nicht geschafft, @code{readline} mit MIT-pThreads zum
Laufen zu bringen. (Das wird zwar nicht benötigt, mag aber für einige
interessant sein.)
@end itemize

@menu
* Windows-Umgebung vorbereiten::  
@end menu

@node Windows-Umgebung vorbereiten,  , MIT-pthreads, MIT-pthreads
@c German node <no English equivalent>
@subsubsection Vorbereitung der Windows-Umgebung

@node Windows source build,  , MIT-pthreads, Installing source
@c German node Windows-Quelldistribution
@subsection Windows-Quelldistribution

Sie benötigen folgendes:

@itemize @bullet
@item
VC++-6.0-Kompiler (aktualisiert mit Service-Pack 4 oder 5 und dem
Präprozessor-Paket). Das Präprozessor-Paket wird für den Makro-Assembler
benötigt. Weitere Details finden Sie unter:
@uref{http://msdn.microsoft.com/vstudio/sp/vs6sp5/faq.asp}.
@item
Die MySQL-Quelldistribution für Windows, die von
@uref{http://www.mysql.com/downloads/} herunter geladen werden kann.
@end itemize

MySQL bauen

@enumerate
@item
Erzeugen Sie ein Arbeitsverzeichnis (z. B. workdir).
@item
Entpacken Sie die Quelldistribution in dieses Verzeichnis.
@item
Starten Sie den VC++-6.0-Kompiler.
@item
Wählen Sie im @code{File}-Menü @code{Open Workspace}.
@item
Öffnen Sie den @file{mysql.dsw}-Workspace, den Sie im Arbeitsverzeichnis
finden.
@item
Wählen Sie im @code{Build}-Menü das @code{Set Active Configuration}-
Menü.
@item
Wählen Sie @code{mysqld - Win32 Debug} und klicken Sie auf OK.
@item
Drücken Sie @code{F7}, um mit dem Bauen des Debug-Servers, der
Bibliotheken und einiger Client-Applikationen zu beginnen.
@item
Wenn das Kompilieren beendet ist, kopieren Sie die Bibliotheken und die
ausführbaren Dateien in ein separates Verzeichnis.
@item
Kompilieren Sie die Release-Versionen, die Sie haben wollen, auf
dieselbe Art.
@item
Erzeugen Sie das Verzeichnis für die MySQL-Dateien, z. B.
@file{c:\mysql}.
@item
Kopieren Sie aus dem Arbeitsverzeichnis folgende Verzeichnisse in das
c:\mysql-Verzeichnis:

@itemize @bullet
@item Data
@item Docs
@item Share
@end itemize

@item
Erzeugen Sie das Verzeichnis @file{c:\mysql\bin} und kopieren Sie alle
Server und Clients, die Sie vorher kompiliert haben, hinein.
@item
Wenn Sie wollen, können Sie auch das @file{lib}-Verzeichnis erzeugen und
die vorher kompilierten Bibliotheken hinein kopieren.
@item
Führen Sie mit Visual Studio ein Clean durch.
@end enumerate

Konfigurieren und starten Sie den Server auf dieselbe Weise wie bei der
Windows-Binärdistribution. @xref{Windows-Umgebung vorbereiten}.


@node Post-installation, Upgrade, Installing source, Installing
@c German node Nach der Installation
@section Einstellungen und Tests nach der Installation

@cindex Nach der Installation, Einstellungen und Tests
@cindex Testen, nach der Installation
@cindex Setup, nach der Installation


Wenn Sie MySQL erst einmal installiert haben (aus einer Binär- oder einer
Quelldistribution), müssen Sie die Berechtigungstabellen (Grant Tables)
initialisieren, den Server starten und sicherstellen, dass der Server
korrekt funktioniert. Eventuell wollen Sie auch einrichten, dass der Server
automatisch gestartet und angehalten wird, wenn Ihr System startet oder
herunter gefahren wird.

Normalerweise installieren Sie die Berechtigungstabellen und starten den
Server wie folgt:
Bei der Installation einer Quelldistribution:
@cindex Start, den Server
@cindex Server, starten

@example
shell> ./scripts/mysql_install_db
shell> cd mysql_installations_verzeichnis
shell> ./bin/safe_mysqld --user=mysql &
@end example

Bei einer Binärdistribution (nicht RPM- oder pkg-Pakete) tun Sie folgendes:

@example
shell> cd mysql_installations_verzeichnis
shell> ./bin/mysql_install_db
shell> ./bin/safe_mysqld --user=mysql &
@end example

Das legt die @code{mysql}-Datenbank an, die alle Zugriffsrechte auf
Datenbanken enthält, die @code{test}-Datenbank, die Sie benutzen können, um
MySQL zu testen und zusätzlich Berechtigungseinträge für den Benutzer, der
@code{mysql_install_db} ausführt sowie einen @code{root}-Benutzer (ohne
Passworte!). Durch den letzten Befehl wird der @code{mysqld}-Server
gestartet.

@code{mysql_install_db} überschreibt keine alten Berechtigungstabellen,
deshalb sollte es unter allen Umständen sicher sein. Wenn Sie die
@code{test}-Datenbank nicht haben wollen, können Sie sie mit
@code{mysqladmin -u root drop test} entfernen.

Am einfachsten läßt sich das Durchtesten vom obersten Verzeichnis der
MySQL-Distribution durchführen. Bei einer Binärdistribution ist das Ihr
Installationsverzeichnis (üblicherweise etwas wie @file{/usr/local/mysql}).
Bei einer Quelldistribution ist es das Hauptverzeichnis Ihres
MySQL-Source-Trees.
@cindex Testen, den Server


In den unten dargestellten Befehlen dieses Abschnitts und der folgenden
Unterabschnitte ist @code{BINDIR} der Pfad zu dem Speicherort, wo Programme
wie @code{mysqladmin} und @code{safe_mysqld} installiert sind. Bei einer
Binärdistribution ist das @file{bin}-Verzeichnis innerhalb der
Distribution. Bei einer Quelldistribution ist @code{BINDIR} wahrscheinlich
@file{/usr/local/bin}, es sei denn, Sie haben ein anderes
Installationsverzeichnis als @file{/usr/local} angegeben, als Sie
@code{configure} laufen ließen. @code{EXECDIR} ist der Speicherort, in dem
der @code{mysqld}-Server installiert ist. Bei einer Binärdistribution ist
das derselbe wie @code{BINDIR}. Bei einer Quelldistribution ist
@code{EXECDIR} wahrscheinlich @file{/usr/local/libexec}.

Das Durchtesten wird im Folgenden detailliert beschrieben.
@cindex Testen, Installation

@enumerate
@item
Falls notwendig, starten Sie den @code{mysqld}-Server und richten die
anfänglichen MySQL-Berechtigungstabellen ein, die alle Zugriffsrechte
enthalten, die festlegen, wie sich Benutzer mit dem Server verbinden
dürfen. Das wird normalerweise mit dem @code{mysql_install_db}-Skript
gemacht:

@example
shell> scripts/mysql_install_db
@end example

Typischerweise müssen Sie @code{mysql_install_db} nur laufen lassen, wenn
Sie MySQL zum ersten Mal installieren. Wenn Sie eine existierende
Installation aktualisieren (Update), können Sie deshalb diesen Schritt
überspringen. (@code{mysql_install_db} ist jedoch ziemlich sicher und
aktualisiert keine bereits existierenden Tabellen, daher können Sie im
Zweifel immer @code{mysql_install_db} laufen lassen.)

@code{mysql_install_db} erzeugt sechs Tabellen (@code{user}, @code{db},
@code{host}, @code{tables_priv}, @code{columns_priv} und @code{func}) in
der @code{mysql}-Datenbank.  Eine Beschreibung der anfänglichen
Zugriffsrechte wird in @ref{Privileges} festgelegt. Kurz gesagt
erlauben diese Zugriffsrechte dem MySQL-Benutzer @code{root}, alles zu tun,
und jedem, Datenbanken anzulegen oder zu benutzen, deren Name @code{'test'}
ist oder mit @code{'test_'} beginnt.

Wenn Sie die Zugriffsberechtigungstabellen (Grant Tables) nicht einrichten,
wird folgender Fehler in der Logdatei erscheinen, wenn Sie den Server
starten:

@tindex host.frm, problems finding
@example
mysqld: Can't find file: 'host.frm'
@end example

Dasselbe kann auch bei einer MySQL-Binärdistribution passieren, wenn Sie
MySQL nicht mit exakt @code{./bin/safe_mysqld} starten!
@xref{safe_mysqld, , @code{safe_mysqld}}.

Eventuell müssen Sie @code{mysql_install_db} als @code{root} laufen lassen.
Wenn Sie wollen, können Sie jedoch den MySQL-Server als unprivilegierter
(non-@code{root})-Benutzer laufen lassen, vorausgesetzt, dieser Benutzer
darf Dateien im Datenbank-Verzeichnis lesen und schreiben. Anweisungen, wie
Sie MySQL als unprivilegierter Benutzer laufen lassen können, finden Sie in
@ref{Privilege changes, , Den MySQL-Benutzer ändern}.

Wenn Sie Probleme mit @code{mysql_install_db} bekommen, sehen Sie bitte
unter @ref{mysql_install_db, , @code{mysql_install_db}} nach.

Es gibt eine Reihe von Alternativen zum Laufenlassen des
@code{mysql_install_db}-Skripts, was mit der MySQL-Distribution
mitgeliefert wird:

@itemize @bullet
@item
Sie können @code{mysql_install_db} editieren, bevor Sie es laufen lassen,
um die anfänglichen Zugriffsrechte zu ändern, die in die Rechtetabellen
installiert werden. Das ist nützlich, wenn Sie MySQL auf einer großen Zahl
von Maschinen mit denselben Zugriffsrechten installieren wollen. In diesem
Fall müssen Sie wahrscheinlich nur ein paar zusätzliche
@code{INSERT}-Statements für die @code{mysql.user}- und
@code{mysql.db}-Tabellen hinzufügen!

@item
Wenn Sie Dinge in den Berechtigungstabellen ändern wollen, nachdem diese
installiert wurden, lassen Sie @code{mysql_install_db} laufen und geben
dann den Befehl @code{mysql -u root mysql} ein, um sich als
MySQL-@code{root}-Benutzer mit den Berechtigungstabellen zu verbinden.
Danach können Sie SQL-Statements eingeben, um die Tabellen direkt zu
verändern.

@item
Es ist möglich, die Berechtigungstabellen komplett neu zu erzeugen, nachdem
Sie angelegt wurden. Das werden Sie zum Beispiel tun wollen, wenn Sie die
Tabellen bereits angelegt haben, Sie nun aber neu anlegen wollen, weil Sie
@code{mysql_install_db} editiert haben.
@end itemize

Zu weiteren Informationen über diese Alternativen siehe
@ref{Privilege system}.

@item
Starten Sie den MySQL-Server wie folgt:

@example
shell> cd mysql_installations_verzeichnis
shell> bin/safe_mysqld &
@end example

Wenn Sie Probleme haben, den Server zu starten, sehen Sie unter
@ref{Starting server} nach.

@item
Benutzen Sie @code{mysqladmin}, um sicherzustellen, dass der Server läuft.
Die folgenden Befehle sind ein einfacher Test, um zu überprüfen, ob der
Server läuft und auf Verbindungen reagiert:

@example
shell> BINDIR/mysqladmin version
shell> BINDIR/mysqladmin variables
@end example

Die Ausgabe von @code{mysqladmin version} kann geringfügig variieren,
abhängig von Ihrer Plattform und der Version von MySQL, sollte aber etwa
wie folgt aussehen:

@example
shell> BINDIR/mysqladmin version
mysqladmin  Ver 8.14 Distrib 3.23.32, for linux on i586
Copyright (C) 2000 MySQL AB & MySQL Finnland AB & TCX DataKonsult AB
This software comes mit ABSOLUTELY NO WARRANTY. This ist free software,
und you are welcome to modify und redistribute it under the GPL license

Server version          3.23.32-debug
Protokoll version        10
Connection              Localhost via Unix socket
TCP port                3306
UNIX socket             /tmp/mysql.sock
Uptime:                 16 sec

Threads: 1  Questions: 9  Slow queries: 0  Opens: 7  Flush tables: 2  Open tables: 0 Queries per second avg: 0.000  Memory in use: 132K  Max memory used: 16773K
@end example

Um ein Gefühl dafür zu bekommen, was Sie sonst noch mit
@code{BINDIR/mysqladmin} tun können, rufen Sie es mit der
@code{--help}-Option auf.

@item
Stellen Sie sicher, dass Sie den Server herunter fahren können:
@cindex Server, Herunterfahren
@cindex Herunterfahren, den Server

@example
shell> BINDIR/mysqladmin -u root shutdown
@end example

@item
Stellen Sie sicher, dass Sie den Server erneut starten können. Tun Sie das
unter Benutzung von @code{safe_mysqld} oder indem Sie @code{mysqld} direkt
aufrufen. Beispiel:

@cindex Server, neu starten
@cindex Neustart, des Servers

@example
shell> BINDIR/safe_mysqld --log &
@end example

Wenn @code{safe_mysqld} fehlschlägt, versuchen Sie, es vom
MySQL-Installationsverzeichnis aus zu starten (falls Sie noch nicht dort
sind). Wenn das nicht funktioniert, sehen Sie unter see @ref{Starting server} nach.

@item
Lassen Sie ein paar einfache Tests ablaufen um sicherzustellen, dass der
Server funktioniert. Die Ausgabe sollte ähnlich der folgenden sein:

@example
shell> BINDIR/mysqlshow
+-----------+
| Databases |
+-----------+
| mysql     |
+-----------+

shell> BINDIR/mysqlshow mysql
Datenbank: mysql
+--------------+
|    Tables    |
+--------------+
| columns_priv |
| db           |
| func         |
| host         |
| tables_priv  |
| user         |
+--------------+

shell> BINDIR/mysql -e "select host,db,user from db" mysql
+------+--------+------+
| host | db     | user |
+------+--------+------+
| %    | test   |      |
| %    | test_% |      |
+------+--------+------+
@end example

Zusätzlich gibt es eine Benchmark-Suite im @file{sql-bench}-Verzeichnis
(unterhalb des MySQL-Installationsverzeichnisses), die Sie benutzen können,
um die Leistungsdaten von MySQL auf verschiedenen Plattformen zu
vergleichen. Das @file{sql-bench/Results}-Verzeichnis enthält die
Ergebnisse vieler Testläufe mit verschiedenen Datenbanken und Plattformen.
Um alle Tests durchzuführen, geben Sie folgende Befehle ein:

@example
shell> cd sql-bench
shell> run-all-tests
@end example

Wenn Sie kein @file{sql-bench}-Verzeichnis haben, benutzen Sie
wahrscheinlich ein RPM für eine Binärdistribution. (Quelldistributions-RPMs
beinhalten das Benchmark-Verzeichnis.) In diesem Fall müssen Sie die
Benchmark-Suite zuerst installieren, bevor Sie sie benutzen können. Ab
MySQL Version 3.22 gibt es Benchmark-RPM-Dateien, die
@file{mysql-bench-VERSION-i386.rpm} benannt sind, die Benchmark-Code und
Daten enthalten.

Wenn Sie eine Quelldistribution haben, können Sie auch die Tests im
@file{tests}-Unterverzeichnis ausführen. Um beispielsweise
@file{auto_increment.tst} auszuführen, geben Sie folgendes ein:

@example
shell> BINDIR/mysql -vvf test < ./tests/auto_increment.tst
@end example

Die Ergebnisse stehen dann in der @file{./tests/auto_increment.res}-Datei.
@end enumerate


@menu
* mysql_install_db::            
* Starting server::             
* Automatic start::             
@end menu

@node mysql_install_db, Starting server, Post-installation, Post-installation
@c German node mysql_install_db
@subsection Probleme mit @code{mysql_install_db}
@cindex @code{mysql_install_db}-Skript
@cindex Skripte, @code{mysql_install_db}

Der Zweck des @code{mysql_install_db}-Skripts ist, neue
MySQL-Berechtigungstabellen zu erzeugen. Es betrifft keine anderen Daten!
Es tut nichts, wenn Sie bereits MySQL-Berechtigungstabellen installiert
haben!

Wenn Sie Ihre Berechtigungstabellen neu erzeugen wollen, sollten Sie den
@code{mysqld}-Server herunter fahren, falls er läuft, und dann etwas
Ähnliches wie folgendes tun:

@example
mv mysql-data-verzeichnis/mysql mysql-data-verzeichnis/mysql-old
mysql_install_db
@end example

Dieser Abschnitt listet Probleme auf, denen Sie vielleicht begegnen, wenn
Sie @code{mysql_install_db} laufen lassen:

@table @strong
@item @code{mysql_install_db} installiert die Berechtigungstabellen nicht.

Eventuell stellen Sie fest, dass @code{mysql_install_db} bei der
Installations der Berechtigungstabellen fehlschlägt und mit folgenden
Meldungen endet:

@example
starting mysqld daemon with databases from XXXXXX
mysql daemon ended
@end example

In diesem Fall sollten Sie einen gründlichen Blick in die Log-Datei werfen!
Diese sollte sich im Verzeichnis @file{XXXXXX} befinden, das in der
Fehlermeldung ausgegeben wird, und sollte anzeigen, warum @code{mysqld}
nicht startete. Wenn Sie nicht verstehen, was passiert ist, schicken Sie
einen Bug-Bericht inklusive Log. Benutzen Sie hierfür @code{mysqlbug}!
@xref{Bug reports}.

@item Es läuft bereits ein @code{mysqld}-Daemon.

In diesem Fall müssen Sie wahrscheinlich @code{mysql_install_db} überhaupt
nicht starten. Sie müssen @code{mysql_install_db} nur einmal starten, und
zwar, wenn Sie MySQL zum ersten Mal installieren.

@item Die Installation eines zweiten @code{mysqld}-Daemons schlägt fehl,
wenn bereits ein Daemon läuft.

Das kann vorkommen, wenn Sie bereits eine existierende MySQL-Installation
haben, aber eine neue Installation an einem anderen Speicherort
unterbringen wollen (zum Beispiel für Testzwecke, oder vielleicht wollen
Sie auch einfach zwei Installationen zugleich laufen lassen. Im Allgemeinen
ist der Grund für das Problem, wenn Sie versuchen, den zweiten Server
laufen zu lassen, dass der zweite Server versucht, denselben Socket und
Port wie der alte zu benutzen. In diesem Fall erhalten Sie als
Fehlermeldung: @code{Can't start server: Bind on TCP/IP port: Address
already in use} oder @code{Can't start server : Bind on unix socket...}.
@xref{Multiple servers}.

@item Sie haben keinen Schreibzugriff auf @file{/tmp}.
@cindex Schreibzugriff, tmp
@cindex Temporäre Datei, Schreibzugriff
@cindex Dateien, @code{tmp}

Wenn Sie keinen Schreibzugriff haben, um eine Socket-Datei am
vorgabemäßigen Ort anzulegen (in @file{/tmp}) oder keine Berechtigung, um
temporäre Dateien in @file{/tmp} anzulegen, erhalten Sie einen Fehler, wenn
Sie @code{mysql_install_db} laufen lassen oder starten oder wenn Sie
@code{mysqld} benutzen.

So können Sie einen anderen Socket und ein anderes temporäres Verzeichnis
festlegen:

@tindex TMPDIR Umgebungsvariable
@tindex MYSQL_UNIX_PORT Umgebungsvariable
@tindex Umgebungsvariable, TMPDIR
@tindex Umgebungsvariable, MYSQL_UNIX_PORT
@example
shell> TMPDIR=/irgendein_temporaeres_verzeichnis/
shell> MYSQL_UNIX_PORT=/irgendein_temporaeres_verzeichnis/mysqld.sock
shell> export TMPDIR MYSQL_UNIX_PORT
@end example

@xref{Problems with mysql.sock}.

@file{irgendein_temporaeres_verzeichnis} sollte der Pfad zu einem
Verzeichnis sein, für das Sie Schreibberechtigung haben.
@xref{Environment variables}.

Danach sollten Sie in der Lage sein, @code{mysql_install_db} laufen zu
lassen und den Server zu starten, und zwar mit folgenden Befehlen:

@example
shell> scripts/mysql_install_db
shell> BINDIR/safe_mysqld &
@end example

@item @code{mysqld} stürzt sofort ab

Wenn Sie RedHat Version 5.0 mit einer Version von @code{glibc} laufen
lassen, die älter als 2.0.7-5 ist, sollten Sie sicherstellen, dass Sie alle
@code{glibc}-Patches installiert haben!
Darüber gibt es jede Menge Informationen in den MySQL-Mail-Archiven. Links
zu den Mail-Archiven finden Sie online unter
@uref{http://www.mysql.com/documentation/}.
Siehe auch @ref{Linux}.

Sie können @code{mysqld} auch manuell starten, dabei die
@code{--skip-grant-tables}-Option benutzen und dann die
Berechtigungsinformationen selbst mit @code{mysql} eintragen:

@example
shell> BINDIR/safe_mysqld --skip-grant-tables &
shell> BINDIR/mysql -u root mysql
@end example

Von @code{mysql} aus geben Sie die SQL-Befehle ein, die in
@code{mysql_install_db} stehen. Stellen Sie sicher, dass Sie danach
@code{mysqladmin flush-privileges} oder @code{mysqladmin reload} laufen
lassen, um dem Server mitzuteilen, die Berechtigungstabellen neu zu laden.
@end table


@node Starting server, Automatic start, mysql_install_db, Post-installation
@c German node Server starten
@subsection Probleme mit dem Start des MySQL-Servers
@cindex Server, Startprobleme
@cindex Probleme, beim Starten des Servers

Wenn Sie Tabellen einsetzen werden, die Transaktionen unterstützen (InnoDB,
BDB), sollten Sie zuerst eine my.cnf-Datei anlegen und die
Startoptionen für die Tabellentypen setzen, die Sie einsetzen wollen.
@xref{Table types}.

Im allgemeinen starten Sie den @code{mysqld}-Server auf eine der drei
folgenden Weisen:

@itemize @bullet
@item
Indem Sie @code{mysql.server} aufrufen. Dieses Skript wird hauptsächlich
beim Systemstart und -herunterfahren eingesetzt. Es wird ausführlicher in
@ref{Automatic start} beschrieben.

@item
Indem Sie @code{safe_mysqld} aufrufen. Dieses Skript versucht die korrekten
Optionen für @code{mysqld} festzustellen und läßt den Server dann mit
diesen Optionen laufen. @xref{safe_mysqld, ,@code{safe_mysqld}}.

@item
Auf Windows NT sollten Sie @code{mysqld} wie folgt als Systemdienst
starten:
@example
bin\mysqld-nt --install               # MySQL als Systemdienst installieren
@end example

Jetzt können Sie @code{mysqld} wie folgt starten / anhalten:
@example
NET START mysql
NET STOP mysql
@end example

Beachten Sie, dass Sie in diesem Fall keine weiteren Optionen für
@code{mysqld} benutzen können!

Sie können den Systemdienst wie folgt entfernen:
@example
bin\mysqld-nt --remove                # MySQL als Systemdienst entfernen
@end example

@item
Indem Sie @code{mysqld} direkt aufrufen.
@end itemize

Wenn der @code{mysqld}-Daemon hoch fährt, wechselt er in das
Daten-Verzeichnis. Dort erwartet er, Log-Dateien und die (process ID)-Datei
schreiben zu können. Ebenfalls erwartet er dort, Datenbanken zu finden.

Der Speicherort des Daten-Verzeichnisses wird zum Zeitpunkt des Kompilierens
der Distribution fest verdrahtet. Wenn @code{mysqld} jedoch erwartet, das
Daten-Verzeichnis irgendwo sonst als an der Stelle zu finden, wo es auf
Ihrem System tatsächlich ist, funktioniert er nicht richtig. Wenn Sie
Probleme mit fehlerhaften Pfaden haben, können Sie durch den Aufruf von
@code{mysqld} mit der @code{--help}-Option herausfinden, welche Optionen
@code{mysqld} erlaubt und was die vorgabemäßigen Pfad-Einstellung sind.
Sie können die Vorgaben überschreiben, indem Sie die korrekten Pfadnamen
als Kommandozeilen-Argumente für @code{mysqld} festlegen. (Diese Optionen
können auch bei @code{safe_mysqld} benutzt werden.)

Normalerweise sollte es lediglich nötig sein, @code{mysqld} das
Basis-Verzeichnis mitzuteilen, wo MySQL installiert ist. Das können Sie mit
der Option @code{--basedir} machen. Zusätzlich können Sie @code{--help}
benutzen, um die Auswirkung der Pfadänderungsoptionen zu überprüfen
(beachten Sie, dass @code{--help} die letzte Option des
@code{mysqld}-Befehls wein @emph{muss}. Beispiel:

@example
shell> EXECDIR/mysqld --basedir=/usr/local --help
@end example

Wenn Sie die Pfadeinstellungen erst einmal festgelegt haben, die Sie
wollen, starten Sie den Server ohne die @code{--help}-Option.

Mit welcher Methode auch immer Sie den Server starten: Wenn er nicht
korrekt hoch fährt, untersuchen Sie die Log-Datei, um zu sehen, ob Sie den
Grund dafür herausfinden können. Log-Dateien liegen im Daten-Verzeichnis
(typischerweise @file{/usr/local/mysql/data} bei einer Binärdistribution,
@file{/usr/local/var} bei einer Quelldistribution und
@file{\mysql\data\mysql.err} unter Windows). Suchen Sie im Daten-Verzeichnis
nach Dateien mit Namen der Form @file{host_name.err} und
@file{host_name.log}, wobei @code{host_name} der Name Ihres Server-Hosts
ist. Sehen Sie in den letzten paar Zeilen dieser Dateien nach:

@example
shell> tail host_name.err
shell> tail host_name.log
@end example

Wenn Sie etwas wie das Folgende in der Log-Datei finden:
@example
000729 14:50:10  bdb:  Recovery function for LSN 1 27595 failed
000729 14:50:10  bdb:  warning: ./test/t1.db: No such file or directory
000729 14:50:10  Can't init databases
@end example

Das bedeutet, dass Sie @code{mysqld} nicht mit @code{--bdb-no-recover}
gestartet haben und Berkeley DB findet, dass etwas mit seinen Log-Dateien
nicht in Ordnung ist, als es versuchte, Ihre Datenbanken
wiederherzustellen. Um weitermachen zu können, sollten Sie alle alten
Berkeley-DB-Log-Dateien aus dem Datenbankverzeichnis an eine andere Stelle
verschieben, wo Sie sie später untersuchen können. Die Log-Dateien sind wie
@file{log.0000000001} benannt, wobei die Nummer im Zeitablauf hochgezählt
wird.

Wenn Sie @code{mysqld} mit BDB-Tabellenunterstützung laufen lassen und
@code{mysqld} beim Start einen Speicherauszug (Core Dump) liefert, könnte
das an Problemen mit den BDB-Wiederherstellungs-Logs liegen. In diesem Fall
können Sie versuchen, @code{mysqld} mit @code{--bdb-no-recover} zu starten.
Wenn das hilft, sollten Sie danach alle @file{log.*}-Dateien aus dem
Daten-Verzeichnis entfernen und versuchen, @code{mysqld} erneut zu starten.

Wenn Sie folgenden Fehler bekommen, bedeutet das, dass ein anderes Programm
(oder ein anderer @code{mysqld}-Server) bereits den TCP/IP-Port oder
-Socket benutzt, den @code{mysqld} versucht zu benutzen:

@example
Can't start server: Bind on TCP/IP-Port: Address already in use
  oder
Can't start server : Bind on unix socket...
@end example

Benutzen Sie @code{ps}, um sicherzustellen, dass kein weiterer
@code{mysqld}-Server läuft. Wenn Sie keinen weiteren Server finden, können
Sie den Befehl @code{telnet ihr-host-name tcp-ip-port-nummer} eingeben und
mehrere Male @code{EINGABE} drücken. Wenn Sie keine Fehlermeldung wie
@code{telnet: Unable to connect to remote host: Connection refused}
erhalten, benutzt irgend etwas anderes den TCP/IP-Port, den @code{mysqld}
versucht zu benutzen. Siehe @ref{mysql_install_db} und @ref{Multiple servers}.

Wenn @code{mysqld} gerade läuft, können Sie herausfinden, welche
Pfadeinstellungen er benutzt, indem Sie folgenden Befehl ausführen:

@example
shell> mysqladmin variables
@end example

oder

@example
shell> mysqladmin -h 'ihr-host-name' variables
@end example

Wenn @code{safe_mysqld} hoch den Server hoch fährt, Sie sich aber nicht mit
ihm verbinden können, stellen Sie sicher, dass Sie einen Eintrag wie den
folgenden in @file{/etc/hosts} haben:

@example
127.0.0.1       localhost
@end example

Dieses Problem tritt nur auf Systemen auf, die keine funktionierende
Thread-Bibliothek besitzen, und für die MySQL so konfiguriert werden muss,
dass es MIT-pThreads benutzt.

Wenn Sie es nicht schaffen, @code{mysqld} zu starten, können Sie versuchen,
eine Trace-Datei anzulegen, um das Problem zu finden. @xref{Making trace files}.

Wenn Sie InnoDB-Tabellen benutzen, sehen Sie bei den InnoDB-spezifischen
Startoptionen nach. @xref{InnoDB start}.

Wenn Sie BDB-(Berkeley DB)-Tabellen benutzen, sollten Sie sich mit den
verschiedenen Startoptionen von BDB vertraut machen. @xref{BDB start}.


@node Automatic start,  , Starting server, Post-installation
@c German node Automatischer Start
@subsection MySQL automatisch starten und anhalten

@cindex Start, Server automatisch starten
@cindex Anhalten, den Server
@cindex Server, starten und anhalten

Die @code{mysql.server}- und @code{safe_mysqld}-Skripte können benutzt
werden, um den Server automatisch beim Hochfahren des Systems zu starten.
@code{mysql.server} kann ebenfalls dazu benutzt werden, den Server
anzuhalten.

Das @code{mysql.server}-Skript kann benutzt werden, um den Server zu
starten oder anzuhalten, indem man es mit den @code{start}- oder
@code{stop}-Argumenten aufruft:

@example
shell> mysql.server start
shell> mysql.server stop
@end example

@code{mysql.server} liegt im @file{share/mysql}-Verzeichnis unterhalb des
MySQL-Installationsverzeichnisses oder im @file{support-files}-Verzeichnis
des MySQL-Source-Trees.

Bevor @code{mysql.server} den Server startet, wechselt es in das
MySQL-Installationsverzeichnis. Dann ruft es @code{safe_mysqld} auf.
Eventuell müssen Sie @code{mysql.server} editieren, wenn Sie eine
Binärdistribution haben, die Sie an eine nicht stardardmäßige Stelle
installiert haben. Ändern Sie es so ab, dass es in das richtige Verzeichnis
wechselt (@code{cd}), bevor es @code{safe_mysqld} startet. Wenn Sie wollen,
dass der Server unter einem bestimmten Benutzer läuft, fügen Sie eine
entsprechende @code{user}-Zeile zur @file{/etc/my.cnf}-Datei hinzu, so wie
weiter unten in diesem Abschnitt dargestellt.

@code{mysql.server stop} hält den Server an, indem es ihm ein Signal
sendet. Sie können den Server auch automatisch herunter fahren, indem Sie
@code{mysqladmin shutdown} ausführen.

Wenn Sie möchten, können Sie diese Start- und Stop-Befehle an den
entsprechenden Stellen Ihrer @file{/etc/rc*}-Dateien einfügen, wenn Sie
MySQL für Produktions-Applikationen benutzen. Beachten Sie, wenn Sie
@code{mysql.server} editieren und dann gelegentlich MySQL aktualisieren
(Update), dass dann Ihre geänderte Version überschrieben wird. Daher
sollten Sie eine Kopie Ihrer editierten Version machen, die Sie erneut
installieren können.

Wenn Ihr System @file{/etc/rc.local} benutzt, um externe Skripte zu
starten, sollten Sie folgendes anhängen:
@example
/bin/sh -c 'cd /usr/local/mysql ; ./bin/safe_mysqld --user=mysql &'
@end example

@cindex Den Speicherort des Sockets ändern
Sie können Optionen für @code{mysql.server} in einer globalen
@file{/etc/my.cnf}-Datei hinzufügen. Eine typische @file{/etc/my.cnf}-Datei
sieht wie folgt aus:

@example
[mysqld]
datadir=/usr/local/mysql/var
socket=/var/tmp/mysql.sock
port=3306
user=mysql

[mysql.server]
basedir=/usr/local/mysql
@end example

Das @code{mysql.server}-Skript kennt folgende Optionen:
@code{datadir}, @code{basedir} und @code{pid-file}.

Folgende Tabelle zeigt, welche Optionsgruppen jedes der Startskripts aus
den Optionsdateien liest:

@multitable @columnfractions .20 .80
@item @strong{Skript} @tab @strong{Optionsgruppen}
@item @code{mysqld} @tab @code{mysqld} und @code{server}
@item @code{mysql.server} @tab @code{mysql.server}, @code{mysqld}, und @code{server}
@item @code{safe_mysqld} @tab @code{mysql.server}, @code{mysqld}, und @code{server}
@end multitable

@xref{Option files}.


@node Upgrade, Operating System Specific Notes, Post-installation, Installing
@c German node Upgrade
@section MySQL aktualisieren (Upgrade / Downgrade)

@cindex Upgrade
@cindex Downgrade

Sie können die MySQL-form- und data-Dateien jederzeit für verschiedene
Versionen auf derselben Architektur benutzen, solange Sie dieselbe
Grundversion von MySQL haben. Die aktuelle Grundversion ist 3. Wenn Sie den
Zeichensatz ändern, während MySQL läuft (was auch die Sortierreihenfolge
betreffen kann), müssen Sie @code{myisamchk -r -q} auf alle Tabellen
ausführen. Ansonsten könnte es sein, dass Ihre Indexe nicht korrekt
sortiert werden.

Wenn Sie vor neuen Versionen zurück schrecken, können Sie Ihren alten
@code{mysqld} zu etwas wie @code{mysqld}-'alte-versions-nummer' umbenennen.
Wenn Ihr neuer @code{mysqld} dann etwas Unerwartetes tut, können Sie ihn
einfach anhalten und mit Ihrem alten @code{mysqld} neu starten!

Wenn Sie ein Upgrade vornehmen, sollte Sie natürlich Ihre alten Datenbanken
sichern.

Wenn Sie nach einem Upgrade auf Probleme mit neu kompilierten
Client-Programmen stoßen, zum Beispiel @code{Commands out of sync} oder
unerwartete Speicherauszüge (Core Dumps), haben sie wahrscheinlich einen
alten Header oder eine alte Bibliotheksdatei benutzt, als Sie die Programme
kompilierten. In diesem Fall sollten Sie das Datum Ihrer
@file{mysql.h}-Datei und @file{libmysqlclient.a}-Bibliothek überprüfen, um
sicherzustellen, dass sie aus der neuen MySQL-Distribution stammten. Wenn
nicht, kompilieren sie Ihre Programme bitte neu!

Wenn Sie Probleme der Art erhalten, dass Ihr neuer @code{mysqld}-Server
nicht startet oder dass Sie sich nicht ohne Passwort verbinden können,
überprüfen Sie, ob Sie nicht etwa noch die alte @file{my.cnf}-Datei Ihrer
alten Installation haben! Sie können das mit @code{program-name
--print-defaults} tun. Wenn es irgend etwas anderes als den Programmnamen
ausgibt, haben Sie eine aktive @code{my.cnf}-Datei, die sich auf die Dinge
auswirkt!

Es ist eine gute Idee, die @code{Msql-Mysql-modules}-Distribution neu zu
bauen und neu zu installieren, wann immer Sie ein neues Release von MySQL
installieren, speziell dann, wenn Sie Symptome wie die bemerken, dass alle
Ihre @code{DBI}-Skripte mit Core-Dumps abbrechen, nachdem Sie MySQL
aktualisiert haben.


@cindex Kompatibilität, zwischen MySQL-Versionen
@cindex Upgrade, 3.23 auf 4.0
@menu
* Upgrading-from-3.23::         
* Upgrading-from-3.22::         
* Upgrading-from-3.21::         
* Upgrading-from-3.20::         
* Upgrading-to-arch::           
@end menu

@node Upgrading-from-3.23, Upgrading-from-3.22, Upgrade, Upgrade
@c German node Upgrading-from-3.23
@subsection Upgrade von 3.23 auf Version 4.0

Sie können Ihre alten data-Dateien ohne jede Änderung mit Version 4.0
benutzen. Wenn Sie Ihre Daten eines MySQL-4.0-Servers für einen älteren
Server verwenden wollen, müssen Sie @code{mysqldump} benutzen.

Alte Clients sollen mit einem Server Version 4.0 ohne jedes Problem
funktionieren.

Die folgende Liste stellt dar, auf was Sie aufpassen müssen, wenn Sie auf
Version 4.0 aktualisieren (Upgrade):

@itemize @bullet
@item
@file{safe_mysqld} wurde zu @file{mysqld_safe} umbenannt.
@item
Die alten C-API-Funktionen @code{mysql_drop_db}, @code{mysql_create_db} und
@code{mysql_connect} werden nicht mehr unterstützt, es sei denn, MySQL wird
mit @code{USE_OLD_FUNCTIONS} kompiliert.
@item
Sie sollten @code{TRUNCATE TABLE} benutzen, wenn Sie alle Zeilen aus einer
Tabelle löschen wollen und Ihnen egal ist, wie viele Zeilen gelöscht
wurden. (@code{TRUNCATE TABLE} ist schneller als @code{DELETE FROM tabelle}).
@item
Sie bekommen einen Fehler, wenn Sie ein aktives @code{LOCK TABLES} oder
eine aktive Transaktion am Laufen haben, wenn Sie versuchen, @code{TRUNCATE
TABLE} oder @code{DROP DATABASE} auszuführen.
@item
Sie sollten Ganzzahl-(Integer)-Werte in BIGINT-Spalten benutzen (anstelle
von Zeichenketten wie in MySQL 3.23). Man kann immer noch Zeichenketten
benutzen, aber die Benutzung von Ganzzahlen ist viel effizienter.
@item
Das Format von @code{SHOW OPEN TABLE} hat sich geändert.
@item
Multithreaded Clients sollten @code{mysql_thread_init()} und
@code{mysql_thread_end()} benutzen. @xref{Threaded clients}.
@end itemize
@node Upgrading-from-3.22, Upgrading-from-3.21, Upgrading-from-3.23, Upgrade
@c German node Upgrading-from-3.22
@subsection Upgrade von einer Version 3.22 auf 3.23

@cindex Kompatibilität, zwischen MySQL-Versionen
@cindex Upgrade, 3.22 to 3.23

MySQL-Version 3.23 unterstützt Tabellen des neuen @code{MyISAM}-Typs und
des alten @code{ISAM}-Typs. Sie müssen Ihre alten Tabellen nicht
konvertieren, um sie mit Version 3.23 einsetzen zu können. Vorgabemäßig
werden alle neuen Tabellen mit dem Typ @code{MyISAM} angelegt (es sei denn,
Sie starten @code{mysqld} mit der @code{--default-table-type=isam}-Option).
Sie können eine @code{ISAM}-Tabelle zu einer @code{MyISAM}-Tabelle mit
@code{ALTER TABLE tabelle TYPE=MyISAM} konvertieren oder mit dem
Perl-Skript @code{mysql_convert_table_format}.

Clients der Versionen 3.22 und 3.21 funktionieren ohne jedes Problem mit
einem Server der Version 3.23.

Die folgende Liste stellt dar, auf was Sie aufpassen müssen, wenn Sie auf
Version 3.23 aktualisieren (Upgrade):

@itemize @bullet
@item
Alle Tabellen, die den @code{tis620}-Zeichensatz benutzen, müssen mit
@code{myisamchk -r} oder @code{REPAIR TABLE} in Ordnung gebracht werden.

@item
Wenn Sie ein @code{DROP DATABASE} auf eine mit symbolischem Link verknüpfte
Datenbank ausführen, werden sowohl der symbolische Links als auch die
Datenbank gelöscht. (Das war in Version 3.22 nicht der Fall, weil configure
den @code{readlink}-Systemaufruf nicht erkannte).

@item
@code{OPTIMIZE TABLE} funktioniert jetzt nur bei @strong{MyISAM}-Tabellen.
Bei anderen Tabellentypen können Sie @code{ALTER TABLE} benutzen, um die
Tabelle zu optimieren. Während der Ausführung von @code{OPTIMIZE TABLE}
wird die Tabelle jetzt vor dem Zugriff anderer Threads gesperrt.

@item
Der MySQL-Client @code{mysql} wir jetzt vorgabemäßig mit der Option
@code{--no-named-commands (-g)} gestartet. Diese Option kann mit
@code{--enable-named-commands (-G)} abgeschaltet werden. Dies kann ein paar
Inkompatibilitätsprobleme verursachen, zum Beispiel in SQL-Skripten, die
benannte (named) Befehle ohne ein Semikolon! Befehle im Langformat dagegen
funktionieren noch auf der ersten Zeile.
@c Question: ... still work from the first line?
some cases, für Beispiel in SQL Skripts that use named Befehle ohne a
semicolon!  Long format Befehle still work from the first line.

@item
If you are using the @code{german} character sort order, you must repair
all your Tabellen mit @code{isamchk -r}, as we have made some changes in
the sort order!

@item
The default return type of @code{IF} will now depend on both arguments
und not only the first argument.

@item 
@code{AUTO_INCREMENT} funktioniert nicht mit negativen Zahlen. Der Grund
liegt darin, dass negative Zahlen beim Übergang von -1 auf 0 Probleme
verursachen. @code{AUTO_INCREMENT} wird jetzt bei MyISAM-Tabellen auf einem
niedrigeren Level gehandhabt und ist viel schneller als vorher. Bei
MyISAM-Tabellen werden alte Zahlen auch nicht mehr wieder benutzt, selbst
wenn Sie einige Zeilen aus der Tabelle löschen.

@item 
@code{CASE}, @code{DELAYED}, @code{ELSE}, @code{END}, @code{FULLTEXT}, 
@code{INNER}, @code{RIGHT}, @code{THEN} und @code{WHEN} sind jetzt
reservierte Wörter.

@item 
@code{FLOAT(X)} ist jetzt ein echter Fließkomma-Typ und kein Wert mit
einer festen Anzahl von Dezimalstellen.

@item 
Wenn Sie @code{DECIMAL(length,dec)} deklarieren, beinhaltet das
Längen-Argument nicht mehr den Platz für das Vorzeichen oder den
Dezimalpunkt.

@item 
Eine @code{TIME}-Zeichenkette muss jetzt von einem der folgenden Formate
sein:
@code{[[[DAYS] [H]H:]MM:]SS[.bruchteil]} oder
@code{[[[[[H]H]H]H]MM]SS[.bruchteil]}

@item 
@code{LIKE} vergleicht jetzt Zeichenketten unter Verwendung derselben
Vergleichsregeln wie @code{'='}. Wenn Sie das alte Verhalten benötigen,
können Sie MySQL mit dem @code{CXXFLAGS=-DLIKE_CMP_TOUPPER}-Flag
kompilieren.

@item 
@code{REGEXP} arbeitet jetzt bei normalen (nicht binären) Zeichenketten
unabhängig von der Groß-/Kleinschreibung.

@item 
Wenn Sie Tabellen prüfen / reparieren, sollten Sie @code{CHECK TABLE} oder
@code{myisamchk} für @code{MyISAM}-Tabellen (@code{.MYI}) benutzen und
@code{isamchk} für ISAM-Tabellen (@code{.ISM}).

@item 
Wenn Sie wollen, dass @code{mysqldump}-Dateien zwischen MySQL-Version 3.22
und Version 3.23 kompatibel sind, sollten Sie nicht die @code{--opt}- oder
@code{--full}-Option für @code{mysqldump} benutzen.

@item 
Überprüfen Sie Ihre Aufrufe von @code{DATE_FORMAT()} und stellen Sie
sicher, dass vor jedem Formatierungszeichen ein @samp{%} steht. (Spätere
MySQL-Versionen 3.22 ließen diese Syntax zu.)

@item
@code{mysql_fetch_fields_direct} ist jetzt eine Funktion (es war ein Makro)
und gibt einen Zeiger auf @code{MYSQL_FIELD} anstelle eines
@code{MYSQL_FIELD} zurück.

@item
@code{mysql_num_fields()} kann nicht mehr für ein @code{MYSQL*}-Objekt
benutzt werden (es ist jetzt eine Funktion, die @code{MYSQL_RES*} als
Argument nimmt. Sie sollten jetzt statt dessen @code{mysql_field_count()}
benutzen.

@item
In MySQL-Version 3.22 war die Ausgabe von @code{SELECT DISTINCT ...} fast
immer sortiert. In Version 3.23 müssen Sie @code{GROUP BY} oder @code{ORDER
BY} benutzen, um eine sortierte Ausgabe zu erhalten.

@item
@code{SUM()} gibt jetzt @code{NULL} zurück statt 0, wenn es keine überein
stimmenden Zeilen gibt. Das ist in Übereinstimmung mit ANSI-SQL.

@item
Ein @code{AND} oder @code{OR} mit @code{NULL}-Werten gibt jetzt @code{NULL}
anstelle von 0 zurück. Das betrifft hauptsächlich Anfragen, die @code{NOT}
bei einem @code{AND/OR}-Ausdruck wie @code{NOT NULL} = @code{NULL}
benutzen.
@code{LPAD()} und @code{RPAD()} kürzen die Ergebnis-Zeichenkette, wenn sie
länger als das Längen-Argument ist.
@end itemize

@node Upgrading-from-3.21, Upgrading-from-3.20, Upgrading-from-3.22, Upgrade
@c German node Upgrading-from-3.21
@subsection Upgrade von Version 3.21 auf Version 3.22

@cindex Kompatibilität, zwischen MySQL-Versionen
@cindex Upgrade, 3.21 auf 3.22

Nichts, was die Kompatibilität betrifft, hat sich zwischen Version 3.21 und
3.22 geändert. Die einzige Falle ist die, dass neue Tabellen, die unter
Verwendung des @code{DATE}-Typs erzeugt werden, die neue Art der
Datenspeicherung benutzen. Diese neuen Felder kann man daher nicht von
einer alten Version von @code{mysqld} ansprechen.

Nachdem Sie MySQL-Version 3.22 installiert haben, starten Sie den neuen
Server und lassen dann das @code{mysql_fix_privilege_tables}-Skript laufen.
Dieses fügt die neuen Zugriffsberechtigungen ein, die Sie benötigen, um den
@code{GRANT}-Befehl zu benutzen. Wenn Sie das vergessen, erhalten Sie ein
@code{Access denied}, wenn Sie versuchen, @code{ALTER TABLE}, @code{CREATE
INDEX} oder @code{DROP INDEX} zu benutzen. Wenn Ihr MySQL-Root ein Passwort
benötigt, müssen Sie dieses als Argument zu
@code{mysql_fix_privilege_tables} angeben.

Die C-API-Schnittstelle für @code{mysql_real_connect()} hat sich geändert.
Wenn Sie ein altes Client-Programm haben, das diese Funktion aufruft,
müssen Sie eine @code{0} als neues @code{db}-Argument einfügen (oder den
Client neu kodieren, so dass er das @code{db}-Element für schnellere
Verbindungen benutzt). Zusätzlich müssen Sie @code{mysql_init()} aufrufen,
bevor Sie @code{mysql_real_connect()} aufrufen! Diese Änderung wurde
durchgeführt, damit die neue @code{mysql_options()}-Funktion in der
@code{MYSQL}-Handler-Struktur Optionen speichern kann.

The @code{mysqld}-Variable @code{key_buffer} wurde umbenannt in
@code{key_buffer_size}, Sie können aber in Ihren Startdateien immer noch
den alten Namen verwenden.


@node Upgrading-from-3.20, Upgrading-to-arch, Upgrading-from-3.21, Upgrade
@c German node Upgrading-from-3.20
@subsection Upgrade von Version 3.20 auf Version 3.21

@cindex Upgrade, 3.20 auf 3.21

Wenn Sie eine Version benutzen, die älter als Version 3.20.28 ist, und auf
Version 3.21 umstellen wollen, müssen Sie folgendes tun:

Sie können den @code{mysqld}-Server Version 3.21 mit @code{safe_mysqld
--old-protocol} starten, um ihn mit Clients aus einer Distribution Version
3.20 zu benutzen. In diesem Fall gibt die neue Client-Funktion
@code{mysql_errno()} überhaupt keine Server-Fehler zurück, nur
@code{CR_UNKNOWN_ERROR} (funktioniert aber bei Client-Fehlern), und der
Server benutzt die alte @code{password()}-Überprüfung statt der neuen.

Wenn Sie die @code{--old-protocol}-Option @strong{NICHT} für @code{mysqld}
benutzen, müssen Sie folgende Änderungen durchführen:

@itemize @bullet
@item
Jeder Client-Code muss neu kompiliert werden. Wenn Sie ODBC benutzen,
müssen Sie die neuen @strong{MyODBC}-2.x-Treiber verwenden.
@item
Sie müssen das Skript @code{Skripts/add_long_password} laufen lassen, um
das @code{Password}-Feld in der @code{mysql.user}-Tabelle zu
@code{CHAR(16)} zu ändern.
@item
Alle Passwörter müssen in der @code{mysql.user}-Tabelle neu zugewiesen
werden (um 62-Bit- statt 31-Bit-Passwörter zu erhalten).
@item
Das Tabellenformat hat sich nicht geändert, daher müssen Sie keinerlei
Tabellen konvertieren.
@end itemize

MySQL-Version 3.20.28 und höher kann das neue @code{user}-Tabellenformat
handhaben, ohne sich auf Clients auszuwirken. Wenn Sie eine MySQL-Version
vor Version 3.20.28 haben, funktionieren Passwörter damit nicht mehr, wenn
Sie die @code{user}-Tabelle konvertieren. Um auf Nummer Sicher zu gehen,
sollten Sie mindestens auf Version 3.20.28 aktualisieren und erst dann auf
Version 3.21.

@cindex Protokoll-Unverträglichkeit
Der neue Client-Code funktioniert bei einem 3.20.x @code{mysqld}-Server.
Wenn Sie daher Probleme mit 3.21.x bekommen, können Sie den alten
3.20.x-Server benutzen, ohne die Clients neu kompilieren zu müssen.

Wenn Sie nicht die @code{--old-protocol}-Option für @code{mysqld} benutzen,
werden alte Clients folgende Fehlermeldung ausgeben:

@example
ERROR: Protocol mismatch. Server Version = 10 Client Version = 9
@end example

Die neue Perl-@code{DBI}/@code{DBD}-Schnittstelle unterstützt auch die alte
@code{mysqlperl}-Schnittstelle. Die einzige Änderung, die Sie machen
müssen, wenn Sie @code{mysqlperl} benutzen, ist, die Argumente für die
@code{connect()}-Funktion zu ändern. Die neuen Argumente sind: @code{host},
@code{database}, @code{user} und @code{password} (die @code{user}- und
@code{password}-Argumente haben die Plätze getauscht.
@xref{Perl DBI Class, , Perl-@code{DBI}-Klasse}.

Folgende Änderungen können Anfragen in alten Applikationen betreffen:

@itemize @bullet
@item
@code{HAVING} muss jetzt vor einer möglichen @code{ORDER BY}-Klausel
spezifiziert werden.
@item
Die Parameter für @code{LOCATE()} wurden getauscht.
@item
Es gibt einige neue reservierte Wörter. Die wichtigsten sind @code{DATE},
@code{TIME} und @code{TIMESTAMP}.
@end itemize


@node Upgrading-to-arch,  , Upgrading-from-3.20, Upgrade
@c German node Upgrading-to-arch
@subsection Upgrade auf eine andere Architektur

@cindex Upgrade, auf andere Architektur

Wenn Sie MySQL-Version 3.23 benutzen, können Sie die @code{.frm}-,
@code{.MYI}- und @code{.MYD}-Dateien zwischen verschiedenen Architekturen
kopieren, die dasselbe Fließkomma-Format unterstützen. (MySQL kümmert sich
um eventuelle Byte-Tausch-Belange.)

Die MySQL-@code{ISAM}-Daten und Index-Dateien (@file{.ISD} und
@file{*.ISM}, je nachdem) sind Architektur-abhängig und in manchen Fällen
Betriebssystem-abhängig. Wenn Sie Ihre Applikationen auf eine andere
Maschine mit einer unterschiedlichen Architektur oder einem anderen
Betriebssystem verlagern wollen, wollten Sie nicht einfach eine Datenbank
verschieben, indem Sie deren Dateien auf die andere Maschine kopieren.
Benutzen Sie statt dessen @code{mysqldump}.

Vorgabemäßig erzeugt @code{mysqldump} eine Datei mit SQL-Statements. Sie
können diese Datei auf die andere Maschine übertragen und Sie als Eingabe
für den @code{mysql}-Client benutzen.

@code{mysqldump --help} zeigt Ihnen, welche Optionen verfügbar sind. Wenn
Sie die Daten mit einer neueren Version von MySQL benutzen werden, sollten
Sie @code{mysqldump --opt} mit der neueren Version benutzen, um einen
schnellen, kompakten Dump zu erhalten.

Die einfachste (wenngleich nicht schnellste) Art, eine Datenbank von einer
Maschine auf eine andere zu bringen, ist, die folgenden Befehle auf der
Maschine auszuführen, auf der die Datenbank liegt:

@example
shell> mysqladmin -h 'anderer hostname' create db_name
shell> mysqldump --opt db_name \
        | mysql -h 'anderer hostname' db_name
@end example

Wenn Sie eine Datenbank von einer entfernten Maschine über ein langsames
Netzwerk kopieren wollen, können Sie folgendes benutzen:

@example
shell> mysqladmin create db_name
shell> mysqldump -h 'anderer hostname' --opt --compress db_name \
        | mysql db_name
@end example

Sie können das Ergebnis auch in einer Datei speichern, diese Datei auf die
Zielmaschine übertragen und dort in die Datenbank laden. Sie können zum
Beispiel wie folgt die Datenbank in eine Datei auf der Quellmaschine
ausgeben (dumpen):

@example
shell> mysqldump --quick db_name | gzip > db_name.inhalte.gz
@end example

(Die in diesem Beispiel erzeugte Datei ist komprimiert.) Übertragen Sie die
Datei, die die Datenbankinhalte enthält, auf die Zielmaschine und geben Sie
dort diese Befehle ein:

@example
shell> mysqladmin create db_name
shell> gunzip < db_name.inhalte.gz | mysql db_name
@end example

@cindex @code{mysqldump}
@cindex @code{mysqlimport}
Sie können auch @code{mysqldump} und @code{mysqlimport} benutzen, um den
Datenbank-Transfer zu bewerkstelligen.
Das ist bei großen Tabellen wesentlich schneller als die Benutzung von
@code{mysqldump}. In den unten dargestellten Befehlen repräsentiert
@code{DUMPDIR} den vollen Pfadnamen des Verzeichnisses, das Sie benutzen,
um die Ausgabe von @code{mysqldump} zu speichern.

Legen Sie zunächst das Verzeichnis für die Ausgabe-Dateien an und geben Sie
die Datenbank aus (Dump):

@example
shell> mkdir DUMPDIR
shell> mysqldump --tab=DUMPDIR db_name
@end example

Übertragen Sie dann die Dateien des @code{DUMPDIR}-Verzeichnisses in ein
entsprechendes Verzeichnis auf der Zielmaschine und laden Sie dort die
Dateien in MySQL:

@example
shell> mysqladmin create db_name           # Datenbank erzeugen
shell> cat DUMPDIR/*.sql | mysql db_name   # Tabellen in der Datenbank erzeugen
shell> mysqlimport db_name DUMPDIR/*.txt   # Daten in die Tabellen laden
@end example

Vergessen Sie auch nicht, die @code{mysql}-Datenbank zu kopieren, den dort
befinden Sie die Berechtigungstabellen (@code{user}, @code{db},
@code{host}). Eventuell müssen Sie die Befehle als
MySQL-@code{root}-Benutzer auf der neuen Maschine eingeben, um die
@code{mysql}-Datenbank angelegt zu bekommen.

Nachdem Sie die @code{mysql}-Datenbank auf die neue Maschine kopiert haben,
führen Sie @code{mysqladmin flush-privileges} aus, damit der Server die
Berechtigungsinformationen neu einliest.


@node Operating System Specific Notes, Perl support, Upgrade, Installing
@c German node Clientseitig
@section Betriebssystem-spezifische Anmerkungen



@menu
* Linux::                       
* Windows::                     
* Solaris::                     
* BSD Notes::                   
* Mac OS X::                    
* Other Unix Notes::            
* OS/2::                        
* BeOS::                        
* Novell Netware::              
@end menu

@node Linux, Windows, Operating System Specific Notes, Operating System Specific Notes
@c German node Linux
@subsection Linux (alle Linux-Versionen)


Die Anmerkungen weiter unten, die @strong{glibc} betreffen, gelten nur
dann, wenn Sie MySQL selbst bauen. Wenn Sie Linux auf einer x86-Maschine
fahren, ist es in den meisten Fällen wesentlich besser, einfach unsere
Binärdateien zu benutzen. Wir linken unsere Binärdateien an die am besten
gepatchte Version von @strong{glibc}, die wir bieten können, und mit den
besten Kompiler-Optionen, wobei wir versuchen, MySQL für Hochlast-Server
geeignet zu machen. Wenn Sie also den Text unten lesen und sich nicht
sicher sind, was Sie tun sollen, sollten Sie zunächst unsere Binärdateien
ausprobieren, um zu sehen, ob diese Ihren Anforderungen entsprechen.
Kümmern Sie sich nur dann um einen eigenen Build, wenn Sie feststellen,
dass unsere Binärdateien nicht gut genug sind. In diesem Fall wären wir für
einen Hinweis dazu dankbar, damit wir beim nächsten Mal eine bessere
Binärdatei bauen können. Für eine typische Benutzung, selbst bei einer
großen Zahl gleichzeitiger Verbindungen und / oder Tabellen, die größer
als 2 GB sind, sind unsere Binärdateien in den meisten Fällen die beste
Wahl.

MySQL benutzt auf Linux LinuxThreads. Wenn Sie eine alte Linux-Version
benutzen, die keine @code{glibc2} hat, müssen Sie LinuxThreads
installieren, bevor Sie MySQL kompilieren. Sie erhalten LinuxThreads unter
@uref{http://www.mysql.com/downloads/Linux}.

@strong{ACHTUNG:} Wir haben einige seltsame Probleme bei Linux 2.2.14 und
MySQL auf SMP-Systemen festgestellt. Wenn Sie ein SMP-System haben,
empfehlen wir, so schnell wie möglich auf Linux 2.4 zu aktualisieren
(Upgrade)! Dadurch wird Ihr System ausserdem schneller und stabiler!

Beachten Sie, dass @code{glibc}-Versionen vor und einschließlich Version
2.1.1 einen schweren Fehler im @code{pThread_mutex_timedwait}-Handling
haben, was benutzt wird, wenn Sie @code{INSERT DELAYED} verwenden. Wir
empfehlen, vor einem Upgrade der glibc @code{INSERT DELAYED} nicht zu
verwenden.

Wenn Sie planen, mehr als 1000 gleichzeitige Verbindungen zu haben, müssen
Sie einige Änderungen an LinuxThreads vornehmen, es neu kompilieren und mit
der neuen @file{libpThread.a} linken. Setzen Sie @code{PTHREAD_THREADS_MAX} in
@file{sysdeps/unix/sysv/linux/bits/local_lim.h} auf 4096 herauf und setzen
Sie @code{STACK_SIZE} in @file{linuxThreads/internals.h} auf 256 KB
herunter. Die Pfade sind relativ zum Wurzelverzeichnis von @code{glibc}.
Beachten Sie, dass MySQL bei etwa 600 bis 1000 Verbindungen nicht stabil
läuft, wenn @code{STACK_SIZE} auf den Vorgabewert von 2 MB gesetzt wird.

Wenn Sie Probleme damit bekommen, dass MySQL nicht genug Dateien oder
Verbindungen öffnen kann, haben Sie möglicherweise Linux nicht so
konfiguriert, dass es genug Dateien handhaben kann.

In Linux 2.2 und Folgenden können Sie die Anzahl der allozierten
Datei-Handler herausbekommen, wenn Sie folgendes eingeben:

@example
cat /proc/sys/fs/file-max
cat /proc/sys/fs/dquot-max 
cat /proc/sys/fs/super-max
@end example

Wenn Sie mehr als 16M Speicher haben, sollten Sie etwas Ähnliches wie
folgendes in Ihr Boot-Skript (@file{/etc/rc/boot.local} auf SuSE)
eintragen:

@example
echo 65536 > /proc/sys/fs/file-max
echo 8192 > /proc/sys/fs/dquot-max
echo 1024 > /proc/sys/fs/super-max
@end example

Das können Sie auch von der Kommandozeile aus als Root eingeben, aber in
diesem Fall werden die alten Beschränkungen wieder benutzt, wenn Sie Ihren
Computer neu starten.

Zusätzlich sollten Sie in /etc/my.cnf einfügen:

@example
[safe_mysqld]
open-files-limit=8192
@end example

Das sollte MySQL erlauben, bis zu 8192 Verbindungen und Dateien zu
erzeugen.

Die @code{STACK_SIZE}-Konstante in LinuxThreads steuert das Spacing von
Thread-Stacks im Adressraum. Sie muss Groß genug sein, damit reichlich
Platz für den Stack jedes individuellen Threads bleibt, aber klein genug,
um den Stack irgend eines Threads davon abzuhalten, mit den globalen
@code{mysqld}-Daten zu kollidieren. Wie wir durch Experimentieren heraus
fanden, unmappt die Linux-Implementation von @code{mmap()} erfolgreich eine
bereits gemappte Region, wenn Sie sie anweisen, eine Adresse auszumappen,
die bereits in Benutzung ist, wobei sie alle Daten der gesamten Seite auf
Null setzt, statt einen Fehler zurück zu geben. Daher beruht die Sicherheit
von @code{mysqld} oder jeder anderen Thread-Applikation auf dem
"Gentleman"-Verhalten des Codes, der Threads erzeugt. Der Benutzer muss
Vorkehrungen treffen, die sicherstellen, dass die Anzahl laufender Threads
jederzeit ausreichend gering ist, damit die Thread-Stacks sich vom globalen
Heap fernhalten. Bei @code{mysqld} sollten Sie dieses "Gentleman"-Verhalten
forcieren, indem Sie einen vernünftigen Wert für die the
@code{max_connections}-Variable setzen.

Wenn Sie MySQL selbst bauen und sich nicht mit dem Patchen von LinuxThreads
herum plagen wollen, sollten Sie @code{max_connections} auf einen Wert
nicht größer als 500 setzen. Dieser Wert sollte sogar noch kleiner sein,
wenn Sie einen großen Schlüsselpuffer (Key Buffer), große Heap-Tabellen
oder andere Dinge haben, die @code{mysqld} dazu bringen könnten, eine Menge
Speicher zu allozieren, oder wenn Sie einen 2.2-Kernel mit einem 2GB-Patch
fahren. Wenn Sie unsere Binärdateien oder RPM-Versionen 3.23.23 oder später
benutzen, können Sie @code{max_connections} sicher auf 1500 setzen, unter
der Annahme, dass es keine großen Schlüsselpuffer oder Heap-Tabellen mit
vielen Daten gibt. Je mehr Sie @code{STACK_SIZE} in LinuxThreads reduzieren
können, desto mehr können Sie sicher Threads erzeugen. Wir empfehlen einen
Wert zwischen 128K und 256K.

Wenn Sie viele gleichzeitige Verbindungen benutzen, bekommen Sie vielleicht
Probleme durch ein "Feature" im 2.2-Kernel, der einen Prozess dafür
bestraft, dass er sich aufspaltet (fork) oder einen Kindprozess klont, um
einen Fork-Bombenangriff (Fork Bomb Attack) zu verhindern. Das bringt MySQL
dazu, nicht so gut zu skalieren, wenn Sie die Anzahl gleichzeitiger Clients
erhöhen. Wir konnten beobachten, dass sich das auf Einprozessor-Systemen
mit sehr langsamer Thread-Erzeugung bemerkbar macht, was sich darin zeigt,
dass es sehr lange dauern kann, sich mit MySQL zu verbinden (bis zu einer
Minute), und genau so lange, um es herunter zu fahren. Auf
Multiprozessor-Systemen haben wir einen allmählichen Abfall der
Anfrage-Geschwindigkeit beobachtet, wenn die Anzahl der Clients zunimmt. Im
Verlauf der Suche nach einer Lösung haben wir von einem unserer Benutzer
einen Kernel-Patch erhalten, von dem dieser sagt, dass er auf seiner Site
eine beträchtliche Rolle spielt. Der Patch ist hier verfügbar
(@uref{http://www.mysql.com/downloads/patches/linux-fork.patch}).
Inzwischen haben wir recht ausführliche Tests dieses Patchs sowohl auf
Entwicklungs- als auch auf Produktionssystemen gemacht. Er hat die
Performance von @code{MySQL} erheblich verbessert, ohne irgend welche
Probleme zu verursachen, und wir empfehlen ihn jetzt denjenigen unserer
Benutzer, die immer noch Hochlast-Server auf 2.2-Kerneln fahren. Dieses
Problem wurde im 2.4-Kernel behoben. Wenn Sie daher nicht zufrieden mit der
momentanen Performance Ihres Systems sind, ist es wahrscheinlich einfacher,
auf 2.4 zu aktualisieren, statt den 2.2-Kernel zu patchen, was zusätzlich
zur Behebung dieses Fairness-Bugs auch noch Multiprozessor-Systemen einen
netten Schub gibt.

Wir haben MySQL auf dem 2.4-Kernel auf einer Zweiprozessor-Maschine
getestet und haben festgestellt, dass MySQL VIEL bessere Leistungsdaten
bringt - es gab praktisch keine Verlangsamung bei Anfragen bis ganz herauf
zu 1000 Clients, und der Skalierungsfaktor von MySQL (berechnet als
Verhältnis von maximalem Durchsatz zum Durchsatz mit 1 Client) war 100%.
Ähnliches haben wir auf einer Vierprozessor-Maschine beobachtet - praktisch
keine Verlangsamung, während die Anzahl der Clients bis auf 1000 stieg
sowie ein Skalierungsfaktor von 300%. Für einen unter Hochlast fahrenden
Multiprozessor-Server empfehlen wir daher ausdrücklich den 2.4-Kernel.
Weiter haben wir festgestellt, dass es essentiell wichtig ist, den
@code{mysqld}-Prozess auf dem 2.4-Kernel mit der höchstmöglichen Priorität
laufen zu lassen, um maximale Performance zu erreichen. Das kann dadurch
erreicht werden, dass man den @code{renice -20 $$}-Befehl zu
@code{safe_mysqld} hinzufügt. Bei unseren Tests auf der
Vierprozessor-Maschine ergab die Erhöhung der Priorität eine 60%-ige
Steigerung des Durchsatzes bei 400 Clients.

Wir sind derzeit dabei, mehr Informationen über die Performance von
@code{MySQL} auf dem 2.4-Kernel auf 4-Weg- und 8-Weg-Systemen zu bekommen.
Wenn Sie Zugang zu einem solchen System haben und einige Benchmarks gemacht
haben, schicken Sie bitte eine Mail mit den Ergebnissen an
@email{docs@@mysql.com} - wir werden Sie dem Handbuch hinzufügen.

Es gibt eine weitere Sache, die die Performance von MySQL stark
beeinträchtigt, besonders auf SMP-Systemen. Die Implementation von mutex
in LinuxThreads in @strong{glibc-2.1} ist sehr schlecht für Programme mit
vielen Threads, die den mutex nur für kurze Zeit behalten. Wenn Sie MySQL
mit unveränderten @strong{LinuxThreads} linken, führt ironischerweise
auf einem SMP-System in manchen Fällen das Entfernen von Prozessoren zu
einer Leistungssteigerung von MySQL. Für @strong{glibc 2.1.3} haben wir ein
Patch bereit gestellt, um dieses Verhalten zu korrigieren:
@uref{http://www.mysql.com/downloads/Linux/linuxThreads-2.1-patch,linuxThreads-2.1-patch}

Bei Verwendung von @strong{glibc-2.2.2} benutzt MySQL-Version 3.23.36 den
adaptiven mutex, der sogar viel besser als der gepatchte von
@strong{glibc-2.1.3} ist. Seien Sie jedoch davor gewarnt, dass unter
bestimmten Umständen der aktuelle mutex-Code in @strong{glibc-2.2.2}
überdrehen kann, was die Performance von MySQL beeinträchtigt. Die Gefahr,
dass solche Umstände eintreten, kann dadurch verringert werden, dass der
@code{mysqld}-Prozess auf die höchste Priorität gesetzt wird. Zusätzlich
konnten wir das Überdrehverhalten mit einem Patch korrigieren, der
@uref{http://www.mysql.com/downloads/Linux/linuxThreads-2.2.2.patch,hier}
erhältlich ist. Der Patch kombiniert die Korrektur des Überdrehens, die
maximale Anzahl von Threads und das Stack-Spacing in einem. Sie wenden es
auf das @code{linuxThreads}-Verzeichnis mit @code{patch -p0
</tmp/linuxThreads-2.2.2.patch} an. Wir hoffen, dass der Patch in irgend
einer Form in zukünftigen Releases von @code{glibc-2.2} enthalten sein
wird. Wie es auch sei, wenn Sie mit @code{glibc-2.2.2} linken, müssen Sie
immer noch @code{STACK_SIZE} und @code{PTHREAD_THREADS_MAX} korrigieren.
Wir hoffen, dass diese Vorgabewerte zukünftig auf akzeptablere Werte für
eine MySQL-Hochlast-Einrichtung gesetzt werden, so dass Ihr eigener Build
auf @code{./configure; make; make install} reduziert werden kann.

Wir empfehlen, dass Die die oben genannten Patches benutzen, um eine
spezielle statische Version von @code{libpThread.a} zu bauen, die Sie nur
für statisches Linken mit @code{MySQL} benutzen. Wir wissen, dass die
Patches für @code{MySQL} sicher sind und seine Performance erheblich
verbessern, aber wir können diesbezüglich nichts über andere Applikationen
sagen. Wenn Sie andere Applikationen mit der gepatchten Version der
Bibliothek linken oder eine gepatchte gemeinsam benutzte (shared) Version
bauen und auf Ihrem System installieren, tun Sie das auf eigenes Risiko,
was andere Applikationen betrifft, die von @code{LinuxThreads} abhängen.

Wenn Sie während der Installation von MySQL irgend welche seltsamen
Probleme bekommen oder gebräuchliche Utilities hängen bleiben, ist es sehr
wahrscheinlich, dass diese entweder Bibliotheks- oder Compiler-bezogen
sind. In diesem Fall wird die Benutzung unserer Binärdatei sie beheben.

Ein bekanntes Problem der Binärdistribution ist, dass Sie auf älteren
Linux-Systemen, die @code{libc} benutzen (wie RedHat 4.x oder Slackware)
nicht-schwere (non-fatal) Probleme mit der Auflösung von Hostnamen
bekommen.
@xref{Linux-RPM}.

Wenn Sie LinuxThreads benutzen, werden Sie feststellen, dass mindestens
drei Prozesse laufen. Das sind in Wirklichkeit Threads. Es gibt einen
Thread für den LinuxThreads-Manager, einen Thread, um Verbindungen zu
handhaben und einen Thread, um Alarme und Signale zu handhaben.

Beachten Sie, dass der Linux-Kernel und die LinuxThread-Bibliothek
vorgabemäßig nur 1024 Threads haben können. Das bedeutet, dass Sie auf
einem ungepatchten System nur höchstens 1021 Verbindungen zu MySQL haben
können. Die Seite @uref{http://www.volano.com/linuxnotes.html} enthält
Informationen, wie man diese Beschränkung umgeht.

Wenn Sie einen toten @code{mysqld}-Daemon-Prozess mit @code{ps} sehen,
bedeutet das üblicherweise, dass Sie einen Bug in MySQL oder eine zerstörte
Tabelle gefunden haben. @xref{Crashing}.

Um auf Linux einen Speicherauszug (Core Dump) zu erhalten, wenn
@code{mysqld} mit einem SIGSEGV-Signal stirbt, können Sie @code{mysqld} mit
der @code{--core-file}-Option starten. Beachten Sie, dass Sie
wahrscheinlich @code{core file size} hoch setzen müssen, indem Sie
@code{ulimit -c 1000000} zu @code{safe_mysqld} hinzufügen oder
@code{safe_mysqld} mit @code{--core-file-sizes=1000000} starten.
@xref{safe_mysqld, , @code{safe_mysqld}}.

Wenn Sie Ihren eigenen MySQL-Client linken und bei der Ausführung diesen
Fehler erhalten,

@example
ld.so.1: ./my: fatal: libmysqlclient.so.4: open failed: No such file or directory
@end example

kann das Problem durch eine der folgenden Methoden behoben werden:

@itemize @bullet
@item
Linken Sie den Client mit dem folgenden Flag (anstelle von @code{-Lpath}):
@code{-Wl,r/path-libmysqlclient.so}.

@item
Kopieren Sie @code{libmysqclient.so} nach @file{/usr/lib}.

@tindex LD_RUN_PATH Umgebungsvariable
@tindex Umgebungsvariable, LD_RUN_PATH
@item
Fügen Sie der @code{LD_RUN_PATH}-Umgebungsvariablen den Pfadnamen des
Verzeichnisses hinzu, wo @code{libmysqlclient.so} liegt, bevor Sie Ihren
Client laufen lassen.
@end itemize

Wenn Sie den Fujitsu-Compiler @code{(fcc / FCC)} benutzen, werden Sie beim
Kompilieren von MySQL einige Probleme bekommen, weil die
Linux-Header-Dateien sehr @code{gcc}-orientiert sind.

Folgende @code{configure}-Zeile sollte mit @code{fcc/FCC} funktionieren:

@example
CC=fcc CFLAGS="-O -K fast -K lib -K omitfp -Kpreex -D_GNU_SOURCE -DCONST=konstante -DNO_STRTOLL_PROTO" CXX=FCC CXXFLAGS="-O -K fast -K lib  -K omitfp -K preex --no_exceptions --no_rtti -D_GNU_SOURCE -DCONST=konstante -Dalloca=__builtin_alloca -DNO_STRTOLL_PROTO '-D_EXTERN_INLINE=static __inline'" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-low-memory
@end example

@menu
* Binary notes-Linux::          
* Linux-x86::                   
* Linux-SPARC::                 
* Linux-Alpha::                 
* Linux-PowerPC::               
* Linux-MIPS::                  
* Linux-IA64::                  
@end menu

@node Binary notes-Linux, Linux-x86, Linux, Linux
@c German node Linux-Binärdateien
@subsubsection Anmerkungen zur Binärdistribution (Linux)

@cindex Binärdistributionen, unter Linux
@cindex Linux, Binärdistribution

MySQL benötigt zumindest Linux-Version 2.0.

@strong{ACHTUNG}:
Wir haben Berichte von MySQL-Benutzern erhalten, die schwer wiegende
Stabilitätsprobleme mit Linux-Kernel 2.2.14 mitgeteilt haben. Wenn Sie
diesen Kernel benutzen, sollten Sie auf 2.2.19 (oder neuer) oder auf einen
2.4-Kernel aktualisieren. Wenn Sie eine Mehrprozessormaschine haben,
sollten Sie auf jeden Fall in Betracht ziehen, 2.4 zu benutzen, weil Ihnen
das erhebliche Geschwindigkeitssteigerung geben wird.

Die Binärdistribution wird mit @code{-static} gelinkt, was normalerweise
heißt, dass Sie sich nicht um die Version der Systembibliotheken kümmern
müssen, die Sie haben. Ausserdem brauchen Sie nicht LinuxThread
installieren. Ein Programm, das mit @code{-static} gelinkt ist, ist etwas
größer als ein dynamisch gelinktes Programm, und gleichzeitig etwas
schneller (3-5%). Ein Problem liegt jedoch darin, dass Sie bei einem
statisch gelinkten Programm keine benutzerdefinierten Funktionen (UDF)
benutzen können. Wenn Sie UDF-Funktionen schreiben oder benutzen wollen
(das ist nur etwas für C- oder C++-Programmierer), müssen Sie MySQL selbst
kompilieren und das dynamische Linken benutzen.

Wenn Sie ein @code{libc}-basierendes System benutzen (statt eines
@code{glibc2}-Systems), bekommen Sie bei der Binärdistribution
wahrscheinlich Probleme mit der Auflösung von Hostnamen und mit
@code{getpwnam()}. (Das liegt daran, dass @code{glibc} leider von einigen
externen Bibliotheken abhängt, um Hostnamen aufzulösen und und
@code{getpwent()}, selbst wenn es mit @code{-static} kompiliert wird.) In
diesem Fall erhalten Sie wahrscheinlich folgende Fehlermeldung, wenn Sie
@code{mysql_install_db} ausführen:

@example
Sorry, the host 'xxxx' could not be looked up
@end example

oder den folgenden Fehler, wenn Sie versuchen, @code{mysqld} mit der
@code{--user}-Option laufen zu lassen:

@example
getpwnam: No such file or directory
@end example

Sie können dieses Problem auf eine der folgenden Weisen lösen:

@itemize @bullet
@item
Holen Sie sich eine MySQL-Quelldistribution (eine RPM oder die
@code{tar.gz}-Distribution) und installieren Sie statt dessen diese.
@item
Führen Sie @code{mysql_install_db --force} aus. Das führt nicht den
@code{resolveip}-Test in @code{mysql_install_db} aus. Der Nachteil ist,
dass Sie keine Hostnamen in the Berechtigungstabellen benutzen können,
sondern nur IP-Nummern (ausser für @code{localhost}). Wenn Sie ein altes
MySQL-Release benutzen, das @code{--force} nicht unterstützt, müssen Sie
den @code{resolveip}-Test in @code{mysql_install} mit einem Editor
deaktivieren.
@item
Starten Sie @code{mysqld} mit @code{su} anstelle von @code{--user}.
@end itemize

Die Linux-Intel-Binärdatei und die RPM-Releases von MySQL sind für höchst
mögliche Geschwindigkeit konfiguriert. Wir versuchen immer, den schnellsten
stabilen Kompiler zu benutzen, der verfügbar ist.

MySQL-Perl-Unterstützung erfordert Perl-Version 5.004_03 oder neuer.

Auf einigen Linux-2.2-Versionen erhalten Sie womöglich den Fehler
@code{Resource temporarily unavailable}, wenn Sie eine Menge neuer
Verbindungen zu einem @code{mysqld}-Server über TCP/IP aufmachen.

Das Problem liegt darin, dass Linux eine Verzögerung zwischen dem
Schließen eines TCP/IP-Sockets und dem tatsächlichen Freigeben durch das
System hat. Da es nur Platz für eine bestimmte Anzahl von TCP/IP-Slots
gibt, bekommen Sie den genannten Fehler, wenn Sie viele neue
TCP/IP-Verbindungen innerhalb kurzer Zeit aufbauen, zum Beispiel, wenn Sie
den MySQL-@file{test-connect}-Benchmark über TCP/IP laufen lassen.

Wir haben dieses Problem mehrfach an verschiedene Linux-Mailing-Listen
geschrieben, konnten aber bislang keine saubere Lösung erhalten.

Die einzige bekannte 'Behebung' des Problems liegt darin, persistente
Verbindungen bei Ihren Clients zu verwenden oder Sockets zu benutzen, wenn
Sie den Datenbankserver und die Clients auf derselben Maschine laufen
lassen. Wir hoffen, dass zukünftig der @code{Linux 2.4}-Kernel dieses
Problem lösen wird.


@node Linux-x86, Linux-SPARC, Binary notes-Linux, Linux
@c German node Linux-x86
@subsubsection Anmerkungen zu Linux x86

MySQL erfordert @code{libc}-Version 5.4.12 oder neuer. Bekannt ist, dass
@code{libc} 5.4.46 funktioniert. @code{glibc}-Version 2.0.6 und später
sollten ebenfalls funktionieren. Es hat einige Probleme mit den
@code{glibc}-RPMs von RedHat gegeben. Wenn Sie Probleme haben, prüfen Sie
daher, ob es Updates gibt! Die @code{glibc}-2.0.7-19- und -2.0.7-29-RPMs
funktionieren bekanntermaßen ebenfalls.

Bei einigen älteren Linux-Distributionen kann @code{configure} einen Fehler
wie folgt produzieren:

@example
Syntaxfehler in sched.h. Ändern Sie _P zu __P in der
/usr/include/sched.h-Datei. Siehe das Installationskapitel im
Referenzhandbuch.
@end example

Machen Sie, was die (englischsprachige) Fehlermeldung sagt. Fügen Sie also
einen zusätzlichen Unterstrich zum @code{_P}-Makro hinzu, das nur einen
Unterstrich hat, und versuchen Sie es noch einmal.

Möglicherweise erhalten Sie beim Kompilieren Warnungen. Die folgenden davon
können ignoriert werden:

@example
mysqld.cc -o objs-thread/mysqld.o
mysqld.cc: In function `void init_signals()':
mysqld.cc:315: warning: assignment of negative value `-1' to `long unsigned int'
mysqld.cc: In function `void * signal_hand(void *)':
mysqld.cc:346: warning: assignment of negative value `-1' to `long unsigned int'
@end example

In Debian-GNU/Linux müssen Sie folgendes tun, damit MySQL beim Hochfahren
des Systems automatisch startet:

@example
shell> cp support-files/mysql.server /etc/init.d/mysql.server
shell> /usr/sbin/update-rc.d mysql.server defaults 99
@end example

@code{mysql.server} befindet sich im @file{share/mysql}-Verzeichnis
unterhalb des MySQL-Installationsverzeichnisses oder im
@file{support-files}-Verzeichnis des MySQL-Source-Trees.

Wenn @code{mysqld} beim Start immer einen Speicherauszug (Core Dump)
erzeugt, kann das Problem darin liegen, dass Sie eine alte
@file{/lib/libc.a} haben. Versuchen Sie sie umzubenennen, entfernen Sie
dann @file{sql/mysqld}, führen Sie ein neues @code{make install} durch und
versuchen Sie es noch einmal. Dieses Problem wurde von einigen
Slackware-Installationen berichtet.

Wenn Sie beim Linken von @code{mysqld} folgenden Fehler erhalten, bedeutet
das, dass Ihre @file{libg++.a} nicht korrekt installiert ist:

@example
/usr/lib/libc.a(putc.o): In function `_IO_putc':
putc.o(.text+0x0): multiple definition of `_IO_putc'
@end example

Sie können vermeiden, dass @file{libg++.a} benutzt wird, indem Sie
@code{configure} wie folgt ablaufen lassen:

@example
shell> CXX=gcc ./configure
@end example


@node Linux-SPARC, Linux-Alpha, Linux-x86, Linux
@c German node Linux-SPARC
@subsubsection Anmerkungen zu Linux SPARC

Bei einigen Implementationen ist @code{readdir_r()} fehlerhaft. Das äußert
sich darin, dass @code{SHOW DATABASES} immer einen leeren Satz (Empty Set)
zurück gibt. Das kann behoben werden, indem @code{HAVE_READDIR_R} aus


Einige Probleme erfordern, dass Sie Ihre Linux-Installation patchen. Der
Patch befindet sich unter
@uref{http://www.mysql.com/downloads/patches/Linux-sparc-2.0.30.diff}.

Dieser Patch bezieht sich auf Linux-Distribution
@file{sparclinux-2.0.30.tar.gz}, die auf @code{vger.rutgers.edu} verfügbar
ist (eine Version von Linux, die nie mit der offiziellen 2.0.30 verbunden
wurde). Zusätzlich müssen Sie LinuxThreads 0.6 oder neuer installieren.


@node Linux-Alpha, Linux-PowerPC, Linux-SPARC, Linux
@c German node Linux-Alpha
@subsubsection Anmerkungen zu Linux Alpha

MySQL-Version 3.23.12 ist die erste MySQL-Version, die auf Linux-Alpha
getestet wurde. Wenn Sie planen, MySQL auf Linux-Alpha einzusetzen, stellen
Sie sicher, dass Sie diese oder eine neuere Version haben.

Wir haben MySQL auf Alpha mit unseren Benchmarks und unserer Test-Suite
getestet, und es scheint gut zu funktionieren. Hauptsächlich noch nicht
getestet haben wird, wie die Dinge mit vielen gleichzeitigen Verbindungen
funktionieren.

Wir kompilieren die Standard-MySQL-Binärdatei mit SuSE 6.4, Kernel
2.2.13-SMP, Compaq-C-Kompiler Version 6.2-504 und Compaq-C++-Kompiler
Version 6.3-005 auf einer Compaq-DS20-Maschine mit einem
Alpha-EV6-Prozessor.

Sie finden die genannten Kompiler auf
@uref{http://www.support.compaq.com/alpha-tools}). Durch die Verwendung
dieser Kompiler anstelle von gcc erhalten wir eine 9% bis 14% bessere
Performance für MySQL.

Beachten Sie, dass die Konfigurationszeile die Binärversion auf die
aktuelle CPU optimiert. Das heißt, dass Sie unsere Binärdatei nur benutzen
können, wenn Sie einen Alpha-EV6-Prozessor haben. Ausserdem haben wir
statisch kompiliert, um Bibliothek-Probleme zu vermeiden.

@example
CC=ccc CFLAGS="-fast" CXX=cxx CXXFLAGS="-fast -noexceptions -nortti" ./configure --prefix=/usr/local/mysql --disable-shared --with-extra-charsets=complex --enable-thread-safe-client --with-mysqld-ldflags=-non_shared --with-client-ldflags=-non_shared
@end example

Bei Benutzung von egcs funktionierte bei uns die folgende
Konfigurationszeile:

@example
CFLAGS="-O3 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --disable-shared
@end example

Einige bekannte Probleme, wenn MySQL auf Linux-Alpha läuft:

@itemize @bullet
@item
Das Debuggen von threaded Applikationen wie MySQL funktioniert nicht mit
@code{gdb 4.18}. Statt dessen sollten Sie gdb 5.0 herunter laden und
benutzen!

@item
Wenn Sie versuchen, @code{mysqld} unter Benutzung von @code{gcc} statisch
zu linken, wird das resultierende Image beim Starten einen Speicherauszug
(Core Dump) erzeugen. Mit anderen Worten: Benutzen Sie @strong{NICHT}
@code{--with-mysqld-ldflags=-all-static} mit @code{gcc}.
@end itemize


@node Linux-PowerPC, Linux-MIPS, Linux-Alpha, Linux
@c German node Linux-PowerPC
@subsubsection Anmerkungen zu Linux PowerPC

MySQL sollte auf MkLinux mit dem neuesten @code{glibc}-Paket funktionieren
(getestet mit @code{glibc} 2.0.7).


@node Linux-MIPS, Linux-IA64, Linux-PowerPC, Linux
@c German node Linux-MIPS
@subsubsection Anmerkungen zu Linux MIPS

Um MySQL auf Qube2 zum Laufen zu bringen (Linux Mips), benötigen Sie die
neuesten @code{glibc}-Bibliotheken (@code{glibc-2.0.7-29C2} funktioniert
bekanntermaßen). Ausserdem müssen Sie den @code{egcs}-C++-Kompiler
(@code{egcs-1.0.2-9}, @code{gcc 2.95.2} oder neuer) benutzen.


@node Linux-IA64,  , Linux-MIPS, Linux
@c German node Linux-IA64
@subsubsection Anmerkungen zu Linux IA64

Um MySQL auf Linux Ia64 zu kompilieren, mussten wir folgendes tun (wir
vermuten, dass das leichter wird, wenn die neue gcc-Version für ia64
herausgebracht wird).

Unter Verwendung von @code{gcc-2.9-final}:

@example
CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --enable-assembler --with-mysqld-ldflags=-all-static --disable-shared --with-extra-charsets=complex
@end example

Nach @code{make} werden Sie einen Fehler erhalten, dass
@code{sql/opt_range.cc} nicht kompiliert (interner Kompiler-Fehler). Um das
zu beheben, gehen Sie ins sql-Verzeichnis und tippen Sie erneut @code{make}
ein. Kopieren Sie die Kompilierzeile, ändern Sie aber -O2 zu -O0.  Die
Datei sollte nunmehr kompilieren.

Jetzt können Sie folgendes tun:

@example
cd ..
make
make_install
@end example

und @code{mysqld} sollte lauffähig sein.

Auf Ia64 benutzen die MySQL-Client-Binärdateien gemeinsam genutzte (shared)
Bibliotheken. Wenn Sie daher unsere Binärdistribution an anderer Stelle als
@file{/usr/local/mysql} benutzen, müssen Sie entweder
@file{/etc/ld.so.conf} ändern oder den Pfad zum Verzeichnis hinzufügen, wo
Sie @file{libmysqlclient.so} haben, und zwar in der
@code{LD_LIBRARY_PATH}-Umgebungsvariablen.

@xref{Link errors}.

@node Windows, Solaris, Linux, Operating System Specific Notes
@c German node Windows
@subsection Anmerkungen zu Windows

Dieser Abschnitt beschreibt Installation und Benutzung von MySQL auf
Windows. Diese Information steht zusätzlich in der @file{README}-Datei, die
mit der MySQL-Windows-Distribution mitgeliefert wird.



@menu
* Win95 start::                 
* NT start::                    
* Windows running::             
* Windows and SSH::             
* Windows symbolic links::      
* Windows client compiling::    
* Windows vs Unix::             
@end menu

@node Win95 start, NT start, Windows, Windows
@c German node Win95-Start
@subsubsection Wie man MySQL auf Win95 / Win98 startet

MySQL benutzt TCP/IP, um einen Client mit einem Server zu verbinden. (Das
erlaubt jeder beliebigen Maschine in Ihrem Netzwerk, sich mit Ihrem
MySQL-Server zu verbinden.) Aus diesem Grund müssen Sie MySQL auf Ihrer
Maschine installieren, bevor Sie MySQL starten. Sie finden TCP/IP auf Ihrer
Windows-CD-ROM.

Beachten Sie, dass Sie bei Verwendung eines alten Win95-Releases (zum
Beispiel OSR2) wahrscheinlich ist, dass Sie ein altes Winsock-Paket haben!
MySQL erfordert Winsock 2! Sie erhalten das neueste Winsock von
@uref{http://www.microsoft.com/}. Win98 enthält die neue
Winsock-2-Bibliothek, deshalb trifft das Gesagte nicht auf Win98 zu.

Um den @code{mysqld}-Server zu starten, öffnen Sie ein MS-DOS-Fenster
(MS-DOS-Eingabeaufforderung) und geben Sie ein:

@example
C:\> C:\mysql\bin\mysqld
@end example

Das startet @code{mysqld} im Hintergrund ohne Fenster.

Sie können den MySQL-Server killen, indem Sie eingeben:

@example
C:\> C:\mysql\bin\mysqladmin -u root shutdown
@end example

Beachten Sie, dass Win95 und Win98 die Erzeugung von Named Pipes nicht
unterstützen. Auf Win95 und Win98 können Sie Named Pipes nur benutzen, um
sich zu einem entfernten MySQL-Server zu verbinden, der auf einem
NT-Server-Host läuft. (Natürlich muss auch der MySQL-Server Named Pipes
unterstützen. Beispielsweise läßt die Verwendung von @code{mysqld-opt}
unter NT keine Named-Pipe-Verbindungen zu. Sie sollten daher entweder
@code{mysqld-nt} oder @code{mysqld-max-nt} verwenden.)

Wenn @code{mysqld} nicht startet, überprüfen Sie bitte die
@file{\mysql\data\mysql.err}-Datei um zu sehen, ob der Server eine Meldung
ausgegeben hat, die auf die Ursache des Problems hinweist. Sie können auch
versuchen, den Server mit @code{mysqld --standalone} zu starten. In diesem
Fall erscheinen vielleicht nützliche Informationen auf dem Bildschirm, die
Ihnen bei der Lösung des Problems helfen.

Die letzte Option besteht darin, @code{mysqld} mit @code{--standalone
--debug} zu starten. In diesem Fall schreibt @code{mysqld} eine Log-Datei
@file{C:\mysqld.trace}, die die Ursache enthalten könnte, warum
@code{mysqld} nicht startet. @xref{Making trace files}.


@node NT start, Windows running, Win95 start, Windows
@c German node NT-Start
@subsubsection MySQL auf Windows NT oder Windows 2000 starten

Der Win95-/Win98-Abschnitt trifft auch auf NT/Win2000 zu, mit folgenden
Unterschieden:

Damit MySQL mit TCP/IP auf NT läuft, müssen Sie Service-Pack 3 (oder neuer)
installieren!

Beachten Sie, dass alles Folgende, das für NT zutrifft, ebenfalls für
Win2000 zutrifft!

Für NT/Win2000 ist der Servername @code{mysqld-nt}. Normalerweise sollten
Sie MySQL auf NT/Win2000 als Systemdienst installieren:

@example
C:\> C:\mysql\bin\mysqld-nt --install
@end example

oder

@example
C:\> C:\mysql\bin\mysqld-max-nt --install
@end example

(Unter Windows NT können Sie in der Tat jede der Server-Binärdateien als
Systemdienst installieren, aber nur diejenigen, die Namen haben, die auf
@code{-nt.exe} enden, bieten Unterstützung für Named Pipes.)

Sie können MySQL mit diesen Befehlen starten und anhalten:

@example
C:\> NET START mysql
C:\> NET STOP mysql
@end example

Beachten Sie, dass Sie in diesem Fall keine weiteren Optionen für
@code{mysqld-nt} angeben können!

Sie können @code{mysqld-nt} auf NT auch als allein ablaufendes Programm
(Stand-alone) laufen lassen, wenn Sie @code{mysqld-nt} mit irgend welchen
Optionen starten wollen! Wenn Sie @code{mysqld-nt} auf NT ohne Optionen
laufen lassen, versucht @code{mysqld-nt}, sich mit den Vorgabeoptionen als
Systemdienst zu starten. Wenn Sie @code{mysqld-nt} angehalten haben, müssen
Sie es mit @code{NET START mysql} neu starten.

Der Systemdienst wird installiert mit dem Namen @code{MySQL}. Einmal
installiert, muss er mit dem Systemdienst-Steuerungs-Manager (SCM) in der
Systemsteuerung gestartet werden, oder indem Sie den @code{NET START
MySQL}-Befehl benutzen. Wenn irgend welche Optionen angegeben werden
sollen, müssen diese als ``Startparameter'' im SCM-Dienstprogramm angegeben
werden, bevor Sie den MySQL-Dienst starten. Wenn @code{mysqld-nt} läuft,
kann er mit @code{mysqladmin} oder dem SCM-Dienstprogramm angehalten werden, oder
indem Sie den Befehl @code{NET STOP MySQL} benutzen. Wenn Sie SCM benutzen
@code{mysqld-nt}, um den Server anzuhalten, gibt es eine seltsame Meldung
von SCM über @code{mysqld shutdown normally}. Wenn er als Systemdienst
läuft, hat @code{mysqld-nt} keinen Zugriff auf die Konsole. Daher werden
auch keine Meldungen angezeigt.

Auf NT erhalten Sie möglicherweise folgende Systemdienst-Fehlermeldungen:
@c Question: Die folgenden deutschen Meldungen auf NT überprüfen!
@multitable @columnfractions .3 .7
@item Zugriff verboten @tab Bedeutung: @code{mysqld-nt.exe} kann nicht
gefunden werden.
@item Kann nicht registrieren  @tab Bedeutung: Der Pfad ist falsch.
@item Installation des Systemdienstes fehlgeschlagen. @tab Bedeutung: Der
Systemdienst ist bereits installiert oder der
Systemdienst-Steuerungs-Manager ist in einem schlechten Zustand.
@end multitable

Wenn Sie Problem haben, @code{mysqld-nt} als Systemdienst zu installieren,
versuchen Sie, ihn mit dem vollen Pfad zu installieren:

@example
C:\> C:\mysql\bin\mysqld-nt --install
@end example

Wenn das nicht funktioniert, können Sie erreichen, dass @code{mysqld-nt}
korrekt startet, indem Sie den Pfad in der Registrierung korrigieren!

Wenn Sie nicht wollen, dass @code{mysqld-nt} als Systemdienst startet,
können Sie ihn wie folgt starten:

@example
C:\> C:\mysql\bin\mysqld-nt --standalone
@end example

oder

@example
C:\> C:\mysql\bin\mysqld --standalone --debug
@end example

Letztgenanntes gibt Ihnen eine Debug-Spur in @file{C:\mysqld.trace}.
@xref{Making trace files}.


@node Windows running, Windows and SSH, NT start, Windows
@c German node Laufen lassen auf Windows
@subsubsection MySQL auf Windows laufen lassen

@cindex TCP/IP
@cindex Named Pipes

MySQL unterstützt TCP/IP auf allen Windows-Plattformen und Named Pipes auf
NT. Vorgabemäßig werden Named Pipes für lokale Verbindungen auf NT und TCP/IP für
alle anderen Fälle benutzt, wenn der Client TCP/IP installiert hat. Der
Hostname legt fest, welches Protokoll benutzt wird:

@multitable @columnfractions .3 .7
@strong{Hostname} @tab @strong{Protokoll}
@item NULL (keiner) @tab Auf NT zuerst Named Pipes versuchen. Wenn das
nicht funktioniert, TCP/IP benutzen. Auf Win95/Win98 wird TCP/IP benutzt.
@item . @tab Named Pipes
@item localhost @tab TCP/IP zum aktuellen Host
@item hostname  @tab TCP/IP
@end multitable

Sie können erzwingen, dass ein MySQL-Client Named Pipes benutzt, indem Sie
die @code{--pipe}-Option oder @code{.} als Hostnamen angeben. Benutzen Sie
die @code{--socket}-Option, um den Namen der Pipe festzulegen.

Sie können feststellen, ob MySQL funktioniert, indem Sie die folgenden
Befehle eingeben:

@example
C:\> C:\mysql\bin\mysqlshow
C:\> C:\mysql\bin\mysqlshow -u root mysql
C:\> C:\mysql\bin\mysqladmin version status proc
C:\> C:\mysql\bin\mysql test
@end example

Wenn @code{mysqld} nur langsam auf Verbindungen auf Win95/Win98 antwortet,
gibt es wahrscheinlich ein Problem mit Ihrem DNS. Starten Sie in diesem
Fall @code{mysqld} mit @code{--skip-name-resolve} und benutzen Sie nur
@code{localhost} und IP-Nummern in den MySQL Berechtigungstabellen. Sie
können DNS bei einer Verbindung zu einem @code{mysqld-nt}-MySQL-Server, der
auf NT läuft, ebenfalls dadurch vermeiden, dass Sie das
@code{--pipe}-Argument verwenden, um die Benutzung von Named Pipes
festzulegen. Das funktioniert bei den meisten MySQL-Clients.

Es gibt zwei Versionen des MySQL-Kommadozeilen-Werkzeugs:
@multitable @columnfractions .25 .75
@item @code{mysql} @tab Kompiliert auf nativem Windows, was sehr
eingeschränkte Texteditiermöglichkeiten bietet.
@item @code{mysqlc} @tab Kompiliert mit dem Cygnus-GNU-Kompiler und
-Bibliotheken, was @code{readline}-Editiermöglichkeit bietet.
@end multitable

Wenn Sie @code{mysqlc.exe} benutzen wollen, müssen Sie
@file{C:\mysql\lib\cygwinb19.dll} in Ihr Windows-Systemverzeichnis kopieren
(@file{\windows\system} oder ein ähnlicher Ort).

Vorgabemäßig geben die Berechtigungen auf Windows allen lokalen Benutzern
volle Zugriffsrechte auf alle Datenbanken, ohne ein Passwort anzugeben. Um
MySQL sicherer zu machen, sollten Sie für alle Benutzer ein Passwort setzen
und die Zeile in der Tabelle @code{mysql.user}, die @code{Host='localhost'}
und @code{User=''} enthält, löschen.

Sie sollten auch für den @code{root}-Benutzer ein Passwort vergeben. Das
folgende Beispiel entfernt den anonymen Benutzer, der von jedem genutzt
werden kann, um auf die @code{test}-Datenbank zuzugreifen und setzt dann
für den @code{root}-Benutzer ein Passwort:

@example
C:\> C:\mysql\bin\mysql mysql
mysql> DELETE FROM user WHERE Host='localhost' AND User='';
mysql> QUIT
C:\> C:\mysql\bin\mysqladmin reload
C:\> C:\mysql\bin\mysqladmin -u root password ihr_passwort
@end example

Nachdem Sie das Passwort gesetzt haben, sollten Sie den
@code{mysqld}-Server herunter fahren, was Sie mit folgendem Befehl
bewerkstelligen können:

@example
C:\> mysqladmin --user=root --password=ihr_passwort shutdown
@end example

Wenn Sie die alte Shareware-Version von MySQL-Version 3.21 unter Windows
benutzen, schlägt der genannte Befehl mit einem Fehler fehl:
@code{parse error near 'SET OPTION password'}. Die Lösung besteht darin,
auf die aktuelle MySQL-Version zu aktualisieren, die frei verfügbar ist.

Mit den neuen MySQL-Versionen können Sie auf einfache Art neue Benutzer
hinzufügen und Zugriffsrechte mit den @code{GRANT}- und
@code{REVOKE}-Befehlen ändern.
@xref{GRANT}.

@node Windows and SSH, Windows symbolic links, Windows running, Windows
@c German node Windows und SSH
@subsubsection Verbinden mit einem entfernten MySQL-Server von Windows mit SSH aus

@c FIX this ist ugly, real ugly.

@cindex SSH
@cindex Verbinden, auf entfernte Maschine mit SSH

Hier ist eine Anmerkung dazu, wie man sich über eine sichere Verbindung zu
einem entfernten MySQL-Server mit SSH verbindet (von David Carlson
@email{dcarlson@@mplcomm.com}):

@itemize @bullet
@item
Installieren Sie einen SSH-Client auf Ihrer Windows-Maschine. Das beste
nicht kostenlose Werkzeug, das ich gefunden habe, ist @code{SecureCRT} von
@uref{http://www.vundyke.com/}. Eine andere Option ist @code{f-secure} von
@uref{http://www.f-secure.com/}. Sie finden kostenlose Werkzeuge über
@strong{Google} auf
@uref{http://directory.google.com/Top/Computers/Security/Products_and_Tools/Cryptography/SSH/Clients/Windows/}.

@item
Starten Sie Ihren Windows-SSH-Client. 
Konfigurieren Sie: @code{Host_Name = ihr_mysql_server_URL_oder_IP}. 
Konfigurieren Sie: @code{userid=ihre_userid}, um sich an Ihrem Server
anzumelden (wahrscheinlich nicht dasselbe wie Ihr MySQL-Benutzername /
-Passwort).

@item
Konfigurieren Sie Port-Forwarding. Machen Sie entweder ein Remote Forward
(einstellen: @code{local_port: 3306}, @code{remote_host:
ihr_mysql_servername_oder_ip}, @code{remote_port: 3306} ) oder ein lokales
Forward (einstellen: @code{port: 3306},  @code{host: localhost},
@code{remote port: 3306}).

@item
Speichern Sie alles, damit Sie es beim nächsten Mal nicht noch einmal
eingeben müssen.

@item
Melden Sie sich an Ihrem Server mit der SSH-Sitzung, die Sie gerade erzeugt
haben.

@item
Starten Sie auf Ihrer Windows-Maschine irgend eine Applikation wie Access.

@item
Erzeugen Sie unter Windows eine neue Datei und stellen Sie eine Verknüpfung
zu MySQL her, indem Sie den ODBC-Treiber so benutzen, wie Sie es
normalerweise tun, AUSSER dass Sie @code{localhost} als MySQL-Host-Server
eingeben - NICHT @code{yourmysqlservername}.
@end itemize

Jetzt sollten Sie eine ODBC-Verbindung zu MySQL haben, die mit SSH
verschlüsselt ist.


@node Windows symbolic links, Windows client compiling, Windows and SSH, Windows
@c German node Symbolische Links auf Windows
@subsubsection Daten auf verschiedenen Platten unter Win32 aufteilen

@cindex Symbolische Links
@cindex Mehrere Festplatten benutzen, um Daten zu speichern
@c Question: using multiple disks to start data (should be: store data)
@cindex Festplatten, Daten verteilen über mehrere

Ab MySQL-Version 3.23.16 werden die @code{mysqld-max}- und
@code{mysql-max-nt}-Server in der MySQL-Distribution mit der
@code{-DUSE_SYMDIR}-Option kompiliert. Das gibt Ihnen die Möglichkeit,
Datenbanken auf verschiedene Festplatten zu verteilen, indem Sie
symbolische Links darauf machen (in ähnlicher Weise, wie symbolische Links
unter Unix funktionieren).

Unter Windows legen Sie einen symbolischen Link auf eine Datenbank an,
indem Sie eine Datei erzeugen, die den Pfad zum Zielverzeichnis enthält,
und diese Datei im @file{mysql_data}-Verzeichnis unter dem Dateiname
@file{Datenbank.sym} speichern. Beachten Sie, dass der symbolische Link nur
dann benutzt wird, wenn das Verzeichnis @file{mysql_data_dir\datenbank}
nicht existiert.

Wenn Ihr MySQL-Daten-Verzeichnis beispielsweise @file{C:\mysql\data} ist und
Sie die Datenbank @code{foo} dort haben wollen, die aber in
@file{D:\data\foo} liegt, erzeugen Sie die Datei
@file{C:\mysql\data\foo.sym}, die als Text @code{D:\data\foo\} enthält.
Dann werden alle Tabellen, die in der Datenbank @code{foo} sind, in
@file{D:\data\foo} erzeugt.

Beachten Sie, dass wir dieses Feature nicht vorgabemäßig aktiviert haben,
weil es mit Geschwindigkeitsnachteilen verbunden ist. Es ist selbst dann
nicht aktiviert, wenn Sie MySQL mit Unterstützung dafür kompiliert haben.
Um symbolische Links zu aktivieren, müssen Sie in Ihre @code{my.cnf}- oder
@code{my.ini}-Datei folgenden Eintrag machen:

@example
[mysqld]
use-symbolic-links
@end example

In MySQL 4.0 werden symbolische Links vorgabemäßig aktiviert sein. Wenn
Sie dies deaktivieren wollen, benutzen Sie die @code{skip-symlink}-Option.


@node Windows client compiling, Windows vs Unix, Windows symbolic links, Windows
@c German node Windows kompilieren
@subsubsection MySQL-Clients auf Windows kompilieren

@cindex Kompilieren, auf Windows
@cindex Windows, Kompilieren auf

In Ihren Quell-Dateien sollten Sie @file{windows.h} einschließen, bevor
Sie @file{mysql.h} einschließen:

@example
#if defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif
#include <mysql.h>
@end example

Sie können Ihren Code entweder mit der dynamischen
@file{libmysql.lib}-Bibliothek linken, die nur ein Wrapper zum Laden der
@file{libmysql.dll} bei Bedarf ist, oder mit der statischen
@file{mysqlclient.lib}-Bibliothek.

Beachten Sie, dass MySQL-Client-Bibliotheken als threaded Bibliotheken
kompiliert werden, daher sollten Sie auch Ihren Code so kompilieren, dass
er multi-threaded ist!


@node Windows vs Unix,  , Windows client compiling, Windows
@c German node Windows / Unix
@subsubsection MySQL-Windows im Vergleich zu Unix-MySQL

@cindex Windows, im Vergleich zu Unix
@cindex Betriebssysteme, Windows im Vergleich zu Unix

MySQL-Windows hat sich mittlerweile als sehr stabil erwiesen. Diese Version
von MySQL hat dieselben Features wie die entsprechende Unix-Version,
allerdings mit folgenden Ausnahmen:

@table @strong
@item Windows 95 und Threads
Windows 95 hat ein etwa 200 Bytes großes Hauptspeicher-Leck (Memory Leak) für
jede Thread-Erzeugung. Jede Verbindung zu MySQL erzeugt eine neues Thread,
daher sollten Sie @code{mysqld} nicht für längere Zeiträume auf Windows 95
laufen lassen, wenn Ihr Server viele Verbindungen handhabt! Windows NT und
Windows 98 haben diesen Bug nicht.

@item Gleichzeitige Lesezugriffe
MySQL vertraut auf @code{pread()}- und @code{pwrite()}-Aufrufe, um in der
Lage zu sein, @code{INSERT} und @code{SELECT} zu mischen. Momentan benutzen
wir mutexes, um @code{pread()} / @code{pwrite()} zu emulieren. Langfristig
werden wir die Dateiebenen-Schnittstelle durch eine virtuelle Schnittstelle
ersetzen, um die @code{readfile()}- / @code{writefile()}-Schnittstelle auf
NT mit höherer Geschwindigkeit benutzen zu können.
Die aktuelle Implementation begrenzt die Anzahl offener Dateien, die MySQL
benutzen kann, auf 1024, was bedeutet, dass Sie nicht so viele
gleichzeitige Threads auf NT benutzen können wie auf Unix.

@item Blockierendes Lesen
MySQL benutzt blockierendes Lesen (Blocking Read) für jede Verbindung. Das
bedeutet in der Anwendung:

@itemize @bullet
@item
Eine Verbindung wird nicht automatisch nach 8 Stunden abgebaut, wie es
unter der Unix-Version von MySQL der Fall ist.

@item
Wenn eine Verbindung hängen bleibt, ist es unmöglich, sie abzubrechen, ohne
MySQL zu killen.

@item
@code{mysqladmin kill} funktioniert nicht für schlafende Verbindungen.

@item
@code{mysqladmin shutdown} kann nicht abgebrochen werden, solange es noch
schlafende Verbindungen gibt.
@end itemize

Geplant ist, dieses Problem zu beheben, sobald unsere Windows-Entwickler
ein nettes Workaround heraus gefunden haben.

@item UDF-Funktionen
Momentan unterstützt MySQL-Windows keine benutzerdefinierten Funktionen
(UDF, user defined functions).

@item @code{DROP DATABASE}
Sie können keine Datenbank löschen, die durch irgend einen Thread in
Benutzung ist.

@item MySQL vom Task-Manager aus killen
Sie können MySQL nicht vom Task-Manager oder mit dem Shutdown-Dienstprogramm unter
Windows 95 killen. Sie müssen es mit @code{mysqladmin shutdown} herunter
fahren.

@item Von Groß-/Kleinschreibung unabhängige Namen
Unter Windows sind Dateinamen unabhängig von der Groß-/Kleinschreibung.
Daher sind Datenbank- und Tabellennamen in MySQL für Windows ebenfalls
unabhängig von der Groß-/Kleinschreibung. Die einzige Einschränkung ist
die, dass Datenbank- und Tabellennamen innerhalb eines bestimmten
Statements dieselbe Groß-/Kleinschreibung haben müssen.
@xref{Case sensitivity}.

@item Das @samp{\}-Verzeichnis-Zeichen
Bestandteile von Pfadnamen werden unter Windows mit dem @samp{\}-Zeichen
getrennt, das in MySQL als Fluchtzeichen (Escape Character) dient. Wenn Sie
@code{LOAD DATA INFILE} oder @code{SELECT ... INTO OUTFILE} benutzen,
müssen Sie @samp{\} an solchen Stellen doppelt eingeben:

@example
mysql> LOAD DATA INFILE "C:\\tmp\\skr.txt" INTO TABLE skr;
mysql> SELECT * INTO OUTFILE 'C:\\tmp\\skr.txt' FROM skr;
@end example

Alternativ können Sie auch Dateinamen im Unix-Stil mit @samp{/}-Zeichen
benutzen:

@example
mysql> LOAD DATA INFILE "C:/tmp/skr.txt" INTO TABLE skr;
mysql> SELECT * INTO OUTFILE 'C:/tmp/skr.txt' FROM skr;
@end example

@item @code{Can't open named pipe}-Fehler
Wenn Sie MySQL-Version 3.22 auf NT mit den neuesten MySQL-Clients benutzen,
erhalten Sie folgende Fehlermeldung:

@example
error 2017: can't open named pipe to host: . pipe...
@end example

@tindex .my.cnf Datei
Das liegt daran, dass die MySQL-Version für NT auf NT vorgabemäßig Named
Pipes benutzt. Sie können diesen Fehler vermeiden, indem Sie bei den neuen
MySQL-Clients die @code{--host=localhost}-Option benutzen oder eine
Optionsdatei @file{C:\my.cnf} anlegen, die folgendes enthält:

@example
[client]
host = localhost
@end example

@item @code{Access denied for user}-Fehler
Wenn Sie den Fehler @code{Access denied for user: 'ein-benutzer@@unknown'
to database 'mysql'} erhalten, wenn Sie auf einen MySQL-Server auf
derselben Maschine zugreifen, heißt das, dass MySQL Ihren Hostnamen nicht
richtig auflösen kann.

Um das zu beheben, legen Sie eine Datei @file{\windows\hosts} mit folgender
Zeile an:

@example
127.0.0.1       localhost
@end example

@item @code{ALTER TABLE}
Wenn Sie ein @code{ALTER TABLE}-Statement ausführen, ist die Tabelle gegen
Benutzung durch andere Threads gesperrt. Das hat damit zu tun, dass Sie
unter Windows keine Datei löschen können, die durch andere Threads in
Benutzung ist. (Zukünftig finden wir möglicherweise einen Weg, dieses
Problem zu umgehen.)

@item @code{DROP TABLE} auf eine Tabelle, die durch eine
@code{MERGE}-Tabelle in Benutzung ist, funktioniert nicht. Der
@code{MERGE}-Handler führt sein Tabellen-Mapping versteckt vor MySQL durch.
Weil Windows das Löschen von Dateien verbietet, die offen sind, müssen Sie
zuerst alle @code{MERGE}-Tabellen flushen (mit @code{FLUSH TABLES}) oder
die @code{MERGE}-Tabelle löschen, bevor Sie die Tabelle löschen. Wir werden
das zusammen mit der Einführung von Sichten (@code{VIEW}s) beheben.
@end table

Hier sind einige Themen für diejenigen, die uns beim Windows-Release helfen
wollen:

@cindex Windows, offene Fragen

@itemize @bullet
@item
Einen Ein-Benutzer-Server @code{MYSQL.DLL} herstellen. Das könnte alles
beinhalten, was einen Standard-Server ausmacht, ausser Thread-Erzeugung.
Das würde es erheblich erleichtern, MySQL in Applikationen zu benutzen, die
keinen echten Client/Server und keinen Zugriff auf den Server von anderen
Hosts benötigen.

@item
Ein paar nette Start- und Stop-Icons zur MySQL-Installation hinzufügen.

@item
Ein Werkzeug bauen, das Registrierungseinträge für die MySQL-Startoptionen
handhabt. Das Lesen der Registrierungseinträge ist bereits in
@file{mysqld.cc} kodiert, sollte aber umgeschrieben werden, damit es mehr
Parameter-orientiert ist. Das Werkzeug sollte auch in der Lage sein, die
@file{C:\my.cnf}-Optionsdatei zu aktualisieren, wenn der Benutzer diese
lieber als die Registrierungsdatei benutzen will.

@item
Wenn man @code{mysqld} als Systemdienst mit @code{--install} (auf NT)
installiert, wäre es nett, wenn man vorgabemäßige Optionen auf der
Kommandozeile hinzufügen könnte. Im Moment muss man diese fehlende
Möglichkeit durch eine Liste der Parameter in der @file{C:\my.cnf}-Datei
ersetzen.

@item
Es wäre eine feine Sache, wenn man @code{mysqld} vom Task-Manager aus
killen könnte. Momentan muss man @code{mysqladmin shutdown} benutzen.

@item
@code{readline} auf Windows portieren, damit es im
@code{mysql}-Kommandozeilen-Werkzeug benutzt werden kann.

@item
GUI-Versionen der Standard-MySQL-Clients (@code{mysql},
@code{mysqlshow}, @code{mysqladmin} und @code{mysqldump}) wären nett.

@item
Nett wäre auch, wenn die Socket-Lese- und Schreib-Funktionen in
@file{net.c} unterbrechbar wären. Das würde es ermöglichen, offen Threads
mit @code{mysqladmin kill} auf Windows zu killen.

@item
@c Question: Is it my lack of English or why don't I understand the
following two lines?
@code{mysqld} always starts in the "C" locale und not in the default locale.
We would like to have @code{mysqld} use the current locale für the sort order.

@item
Benutzerdefinierte Funktionen (UDF) mit @code{.DLL}s implementieren.

@item
Makros hinzufügen, um die schnelleren, Thread-sicheren
Inkrementierungs-/Dekrementierungsmethoden nutzen zu können, die Windows
bietet.

@end itemize

Weitere Windows-spezifische Themen sind in der @file{README}-Datei
beschrieben, die mit der MySQL-Windows-Distribution ausgeliefert wird.


@node Solaris, BSD Notes, Windows, Operating System Specific Notes
@c German node Solaris
@subsection Anmerkungen zu Solaris

@cindex Installationsprobleme auf Solaris
@cindex Probleme, Installation auf Solaris
@cindex Tar, Probleme auf Solaris
@cindex Fehler, Verzeichnisprüfsumme
@cindex Prüfsummenfehler

Auf Solaris bekommen Sie vielleicht schon Probleme, bevor Sie überhaupt
Ihre MySQL-Distribution entpackt haben! Solaris-@code{tar} kann nicht mit
langen Dateinamen umgehen. Daher sehen Sie vielleicht einen Fehler wie den
folgenden, wenn Sie MySQL entpacken:

@example
x mysql-3.22.12-beta/bench/Results/ATIS-mysql_odbc-NT_4.0-cmp-db2,informix,ms-sql,mysql,oracle,solid,sybase, 0 Bytes, 0 tape blocks
tar: directory checksum error (Verzeichnis-Prüfsummenfehler)
@end example

In diesem Fall müssen Sie GNU-@code{tar} (@code{gtar}) benutzen, um die
Distribution zu entpacken. Sie finden eine vorkompilierte Version für
Solaris auf @uref{http://www.mysql.com/downloads/}.

Native Sun-Threads funktinieren nur auf Solaris 2.5 und höher. Auf 2.4 und
früher benutzt MySQL automatisch MIT-pThreads.
@xref{MIT-pthreads}.

Vielleicht erhalten Sie von configure folgenden Fehler:

@example
checking for restartable system calls... configure: error can not run test
programs while cross compiling
@end example

Das bedeutet, dass mit Ihrer Kompiler-Installation etwas nicht stimmt! In
diesem Fall sollten Sie Ihren Kompiler auf eine neuere Version
aktualisieren. Eventuell sind Sie in der Lage, das Problem zu lösen, indem
Sie folgende Zeile in die @file{config.cache}-Datei einfügen:

@example
ac_cv_sys_restartable_syscalls=$@{ac_cv_sys_restartable_syscalls='no'@}
@end example

Wenn Sie Solaris auf einer SPARC benutzen, ist der empfohlene Kompiler
@code{gcc} 2.95.2. Sie finden ihn auf @uref{http://gcc.gnu.org/}.
Beachten Sie, dass @code{egcs} 1.1.1 und @code{gcc} 2.8.1 auf SPARC nicht
zuverlässig laufen!

Die empfohlene @code{configure}-Zeile ist bei der Benutzung von @code{gcc}
2.95.2:

@example
CC=gcc CFLAGS="-O3" \
CXX=gcc CXXFLAGS="-O3 -felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory --enable-assembler
@end example

Wenn Sie eine Ultra-Sparc haben, erhalten Sie 4 % mehr Performance, wenn
Sie "-mcpu=v8 -Wa,-xarch=v8plusa" zu CFLAGS und CXXFLAGS hinzufügen.

Wenn Sie einen Sun Workshop (Fortre) 5.3 (oder neueren) Kompiler haben,
können Sie @code{configure} wie folgt laufen lassen:

@example
CC=cc CFLAGS="-Xa -fast -xO4 -native -xstrconst -mt" \
CXX=CC CXXFLAGS="-noex -xO4 -mt" \
./configure --prefix=/usr/local/mysql --enable-assembler
@end example

In den MySQL-Benchmarks haben wir auf einer Ultra-Sparc 6%
Geschwindigkeitssteigerung erreicht, wenn wir Sun Workshop 5.3 benutzen, im
Vergleich mit der Benutzung von gcc mit -mcpu-Flags.

Wenn Sie Probleme mit @code{fdatasync} oder @code{sched_yield} bekommen,
können Sie diese beheben, indem Sie @code{LIBS=-lrt} zur
Konfigurationszeile hinzufügen.

Der folgende Absatz ist nur für ältere Kompiler als WorkShop 5.3 relevant:

Eventuell müssen Sie auch das @code{configure}-Skript editieren und
folgende Zeile ändern:

@example
#if !defined(__STDC__) || __STDC__ != 1
@end example

Ändern zu:

@example
#if !defined(__STDC__)
@end example

Wenn Sie @code{__STDC__} mit der @code{-Xc}-Option anschalten, kann der
Sun-Kompiler nicht mit der Solaris-@file{pThread.h}-Header-Datei
kompilieren. Das ist ein Bug von Sun (Kompiler-Problem oder beschädigte
Include-Datei).

Wenn @code{mysqld} beim Laufenlassen eine Fehlermeldung wie die unten
stehende ausgibt, haben Sie versucht, MySQL mit dem Sun-Kompiler zu
kompilieren, ohne die Multi-Thread-Option (@code{-mt}) anzuschalten:

@example
libc internal error: _rmutex_unlock: rmutex not held
@end example

Fügen Sie @code{-mt} zu @code{CFLAGS} und @code{CXXFLAGS} hinzu und
versuchen Sie es noch einmal.

Wenn Sie folgenden Fehler beim Kompilieren von MySQL mit @code{gcc}
erhalten, ist Ihr @code{gcc} nicht für Ihre Version von Solaris
konfiguriert:

@example
shell> gcc -O3 -g -O2 -DDBUG_OFF  -o thr_alarm ...
./thr_alarm.c: In function `signal_hand':
./thr_alarm.c:556: too many arguments to function `sigwait'
@end example

Die einzige richtige Möglichkeit in diesem Fall ist, sich die neueste
Version von @code{gcc} zu besorgen und Sie mit Ihrem aktuellen
@code{gcc}-Kompiler zu kompilieren. Zumindest auf Solaris 2.5 haben fast
alle Binärversionen von @code{gcc} alte, unbrauchbare Include-Dateien, die
alle Programme beschädigen, die Threads benutzen (und möglicherweise auch
andere Programme)!

Solaris stellt keine statischen Versionen aller Systembibliotheken zur
Verfügung (@code{libpThreads} und @code{libdl}). Daher können Sie MySQL
nicht mit @code{--static} kompilieren. Wenn Sie es dennoch versuchen,
erhalten Sie folgenden Fehler:

@example
ld: fatal: library -ldl: not found

oder

undefined reference to `dlopen'

oder

cannot find -lrt
@end example

Wenn zu viele Prozesse zu schnell hintereinander versuchen, sich mit
@code{mysqld} zu verbinden, werden Sie folgenden Fehler im MySQL-Log sehen:

@example
Error in accept: Protocol error
@end example

Als Workaround können Sie versuchen, den Server mit der
@code{--set-variable back_log=50}-Option zu starten. @xref{Command-line options}.

Wenn Sie Ihren eigenen MySQL-Client linken, erhalten Sie möglicherweise
folgenden Fehler, wenn Sie versuchen, ihn auszuführen:

@example
ld.so.1: ./my: fatal: libmysqlclient.so.#: open failed: No such file or directory
@end example

Dieses Problem kann mit einer der folgenden Methoden vermieden werden:

@itemize @bullet
@item
Linken Sie den Client mit folgendem Flag (anstelle von @code{-Lpath}):
@code{-Wl,r/full-path-to-libmysqlclient.so}.

@item
Kopieren Sie @file{libmysqclient.so} nach @file{/usr/lib}.

@tindex LD_RUN_PATH-Umgebungsvariable
@tindex Umgebungsvariable, LD_RUN_PATH
@item
Fügen Sie den Pfadnamen des Verzeichnisses, wo @file{libmysqlclient.so}
liegt, der @code{LD_RUN_PATH}-Umgebungsvariablen hinzu, bevor Sie Ihren
Client laufen lassen.
@end itemize

Wenn Sie die @code{--with-libwrap}-configure-Option benutzen, müssen Sie
auch die Bibliotheken einschließen, die @file{libwrap.a} benötigt:

@example
--with-libwrap="/opt/NUtcpwrapper-7.6/lib/libwrap.a -lnsl -lsocket
@end example

Wenn Sie Probleme mit configure haben, wenn Sie versuchen, mit @code{-lz}
zu linken und keine @code{zlib} installiert haben, haben Sie zwei
Möglichkeiten:

@itemize @bullet
@item
Wenn Sie in der Lage sein wollen, dass komprimierte Kommunikationsprotokoll
zu benutzen, müssen Sie zlib von ftp.gnu.org laden und installieren.

@item
Konfigurieren Sie mit @code{--with-named-z-libs=no}.
@end itemize

Wenn Sie gcc benutzen und Probleme mit dem Laden von @code{UDF}-Funktionen
in MySQL haben, versuchen Sie, @code{-lgcc} zur Link-Zeile für die
@code{UDF}-Funktion hinzuzufügen.

Wenn Sie wollen, dass MySQL automatisch startet, kopieren Sie
@file{Support-files/mysql.server} nach @file{/etc/init.d} und erzeugen Sie
einen symbolischen Link darauf, den Sie @file{/etc/rc3.d/S99mysql.server}
nennen.




@menu
* Solaris 2.7::                 
* Solaris x86::                 
@end menu

@node Solaris 2.7, Solaris x86, Solaris, Solaris
@c German node Solaris 2.7
@subsubsection Anmerkungen zu Solaris 2.7/2.8

Normalerweise können Sie eine Solaris-2.6-Binärdatei für Solaris 2.7 und
2.8 benutzen. Die meisten Dinge, die Solaris 2.6 betreffen, treffen auch
für Solaris 2.7 und 2.8 zu.

Beachten Sie, dass MySQL-Version 3.23.4 und höher in der Lage sein sollte,
automatisch neue Versionen von Solaris zu erkennen und Workarounds für die
folgenden Probleme zu aktivieren!

Solaris 2.7 / 2.8 hat einige Bugs in den Include-Dateien. Eventuell sehen
Sie folgenden Fehler, wenn Sie @code{gcc} benutzen:

@example
/usr/include/widec.h:42: warning: `getwc' redefined
/usr/include/wchar.h:326: warning: this is the location of the previous
definition
@end example

Wenn das auftritt, können Sie folgendes tun, um das Problem zu lösen:

Kopieren Sie @code{/usr/include/widec.h} nach
@code{.../lib/gcc-lib/os/gcc-version/include} und ändern Sie Zeile 41 von:

@example
#if     !defined(lint) && !defined(__lint)

nach

#if     !defined(lint) && !defined(__lint) && !defined(getwc)
@end example

Alternativ können Sie @file{/usr/include/widec.h} direkt editieren. Egal,
wie Sie vorgehen: Nachdem Sie die Fehlerbehebung durchgeführt haben,
sollten Sie @file{config.cache} entfernen und @code{configure} noch einmal
laufen lassen!

Wenn Sie beim Laufenlassen von @code{make} folgende Fehler bekommen, liegt
das daran, dass @code{configure} die @file{curses.h}-Datei nicht erkannte
(vermutlich aufgrund des Fehlers in @file{/usr/include/widec.h}):

@example
In file included by mysql.cc:50:
/usr/include/term.h:1060: syntax error before `,'
/usr/include/term.h:1081: syntax error before `;'
@end example

Das Problem lösen Sie auf eine der folgenden Weisen:

@itemize @bullet
@item
Konfigurieren Sie mit @code{CFLAGS=-DHAVE_CURSES_H CXXFLAGS=-DHAVE_CURSES_H ./configure}.

@item
Editieren Sie @file{/usr/include/widec.h}, wie weiter oben gezeigt, und
lassen Sie configure noch einmal laufen.

@item
Entfernen Sie die @code{#define HAVE_TERM}-Zeile aus der
@file{config.h}-Datei und lassen Sie @code{make} noch einmal laufen.
@end itemize

Wenn Sie das Problem bekommen, dass Ihr Linker @code{-lz} nicht finden
kann, wenn Sie Ihr Client-Programm linken, liegt das wahrscheinlich daran,
dass Ihre @file{libz.so}-Datei in @file{/usr/local/lib} installiert ist.
Sie können das mit einer der folgenden Methoden beheben:

@itemize @bullet
@item
Fügen Sie @file{/usr/local/lib} zu @code{LD_LIBRARY_PATH} hinzu.

@item
Fügen Sie einen Link auf @file{libz.so} von @file{/lib} hinzu.

@item
Wenn Sie Solaris 8 benutzen, können Sie die optionale zlib aus Ihrer
Solaris-8-CD-Distribution installieren.

@item
Konfigurieren Sie MySQL mit der @code{--with-named-z-libs=no}-Option.
@end itemize


@node Solaris x86,  , Solaris 2.7, Solaris
@c German node Solaris x86
@subsubsection Anmerkungen zu Solaris x86

Auf Solaris 2.8 auf x86 erzeugt @code{mysqld} einen Speicherauszug (Core
Dump), wenn Sie darin 'strip' laufen lassen.

Wenn Sie @code{gcc} oder @code{egcs} auf Solaris x86 benutzen und Probleme
mit Speicherauszügen (Core Dumps) unter Last erleben, sollten Sie folgenden
@code{configure}-Befehl benutzen:

@example
CC=gcc CFLAGS="-O3 -fomit-frame-pointer -DHAVE_CURSES_H" \
CXX=gcc \
CXXFLAGS="-O3 -fomit-frame-pointer -felide-constructors -fno-exceptions -fno-rtti -DHAVE_CURSES_H" \
./configure --prefix=/usr/local/mysql
@end example

Das vermeidet Probleme mit der @code{libstdc++}-Bibliothek und mit
C++-Ausnahmefehlern.

Wenn das nicht hilft, sollten Sie eine Debug-Version kompilieren und sie
mit einer Trace-Datei oder unter @code{gdb} laufen lassen. @xref{Using gdb on mysqld}.


@node BSD Notes, Mac OS X, Solaris, Operating System Specific Notes
@c German node BSD
@subsection Anmerkungen zu BSD



@menu
* FreeBSD::                     
* NetBSD::                      
* OpenBSD::                     
* OpenBSD 2.5::                 
* OpenBSD 2.8::                 
* BSDI::                        
* BSDI2::                       
* BSDI3::                       
* BSDI4::                       
@end menu

@node FreeBSD, NetBSD, BSD Notes, BSD Notes
@c German node FreeBSD
@subsubsection Anmerkungen zu FreeBSD

FreeBSD 3.x wird für MySQL empfohlen, weil das Thread-Paket sehr viel
integrierter ist.

Die einfachste und daher empfohlene Art der Installation ist die Benutzung
der mysql-server- und mysql-client-Ports, die auf
@uref{http://www.freebsd.org} verfügbar sind.

Durch deren Benutzung erhalten Sie:
@itemize @bullet
@item
Ein funktionierendes MySQL mit allen Optimierungen bereits aktiviert, von
denen bekannt ist, dass Sie auf Ihrer Version von FreeBSD funktionieren.

@item
Automatische Konfiguration, automatisches Build.

@item
Start-Skripte, die in /usr/local/etc/rc.d installiert werden.

@item
Die Möglichkeit festzustellen, welche Dateien installiert sind, mit
pkg_info -L. Und die Möglichkeit, sie mit pkg_delete zu entfernen, wenn Sie
MySQL nicht mehr auf dieser Maschine haben wollen.
@end itemize

Empfohlen wird die Benutzung von MIT-pThreads auf FreeBSD 2.x und von
nativen Threads auf Version 3 und höher. Es ist möglich, auf einigen späten
2.2.x-Versionen mit nativen Threads zu arbeiten, aber Sie können beim
Herunterfahren von @code{mysqld} Probleme bekommen.

Die MySQL-@file{Makefile}-Dateien erfordern GNU-make (@code{gmake}). Wenn
Sie MySQL kompilieren wollen, müssen Sie zuerst GNU-@code{make}
installieren.

Stellen Sie sicher, dass Ihr Namensauflöser (Name Resolver) korrekt
eingerichtet ist. Ansonsten erleben Sie vielleicht Resolver-Verzögerungen
oder -Fehler, wenn Sie sich mit @code{mysqld} verbinden.

Stellen Sie sicher, dass der @code{localhost}-Eintrag in der
@file{/etc/hosts}-Datei stimmt. Ansonsten werden Sie Probleme haben, sich
mit der Datenbank zu verbinden. Die @file{/etc/hosts}-Datei sollte mit
folgender Zeile beginnen:

@example
127.0.0.1       localhost localhost.ihre.domain
@end example

Wenn Sie bemerken, dass @code{configure} MIT-pThreads benutzen wird, lesen
Sie die Anmerkungen zu MIT-pThreads. @xref{MIT-pthreads}.

Wenn @code{make install} meldet, dass es @file{/usr/include/pThreads} nicht
finden kann, hat @code{configure} nicht entdeckt, dass Sie MIT-pThreads
benötigen. Das kann durch die Ausführung folgender Befehle behoben werden:

@example
shell> rm config.cache
shell> ./configure --with-mit-threads
@end example

FreeBSD ist dafür bekannt, dass es vorgabemäßig einen sehr niedrigen Wert
für Datei-Handles eingestellt hat. @xref{Not enough file handles}.
Kommentieren Sie den Abschnitt ulimit -n section in safe_mysqld aus oder
erhöhen Sie die Werte für den @code{mysqld}-Benutzer in /etc/login.conf
(und bauen Sie es neu mit cap_mkdb /etc/login.conf). Stellen Sie ausserdem
sicher, dass Sie die korrekte Klasse für diesen Benutzer in der
Passwort-Datei einstellen, wenn Sie nicht den Vorgabewert benutzen
(benutzen Sie chpass mysqld-user-name). @xref{safe_mysqld,
,@code{safe_mysqld}}.

Wenn Sie Probleme mit dem aktuellen Datum in MySQL erhalten, wird das
Setzen der @code{TZ}-Variablen das wahrscheinlich beheben.
@xref{Environment variables}.

Um ein sicheres, stabiles System zu erhalten, sollten Sie ausschließlich
FreeBSD-Kernels benutzen, die als @code{-STABLE} markiert sind.


@node NetBSD, OpenBSD, FreeBSD, BSD Notes
@c German node NetBSD
@subsubsection Anmerkungen zu NetBSD

Um auf NetBSD zu kompilieren, benötigen Sie GNU @code{make}. Ansonsten wird
das Kompilieren abstürzen, wenn @code{make} versucht, @code{lint} auf
C++Dateien laufen zu lassen.


@node OpenBSD, OpenBSD 2.5, NetBSD, BSD Notes
@c German node OpenBSD
@subsubsection Anmerkungen zu OpenBSD



@node OpenBSD 2.5, OpenBSD 2.8, OpenBSD, BSD Notes
@c German node <no English equivalent>
@subsubsection Anmerkungen zu OpenBSD 2.5

Auf OpenBSD-Version 2.5 können Sie MySQL mit nativen Threads mit folgenden
Optionen kompilieren:

@example
CFLAGS=-pThread CXXFLAGS=-pThread ./configure --with-mit-threads=no
@end example


@node OpenBSD 2.8, BSDI, OpenBSD 2.5, BSD Notes
@c German node OpenBSD 2.8
@subsubsection Anmerkungen zu OpenBSD 2.8

Unsere Benutzer haben berichtet, dass OpenBSD 2.8 einen Thread-Bug hat, der
Probleme mit MySQL verursacht. Die OpenBSD-Entwickler haben das Problem
behoben, aber seit dem 25. Januar 2001 ist es nur im ``-current''-Zweig
verfügbar. Die Symptome dieses Thread-Bugs sind langsames Antworten, hohe
Lase, hohe Prozessorauslastung und Abstürze.


@node BSDI, BSDI2, OpenBSD 2.8, BSD Notes
@c German node BSDI
@subsubsection Anmerkungen zu BSD/OS



@node BSDI2, BSDI3, BSDI, BSD Notes
@c German node <no English equivalent>
@subsubsection Anmerkungen zu BSD/OS Version 2.x

Wenn Sie folgenden Fehler beim Kompilieren von MySQL erhalten, ist Ihr
@code{ulimit}-Wert für virtuellen Speicher zu niedrig:

@example
item_func.h: In method `Item_func_ge::Item_func_ge(const Item_func_ge &)':
item_func.h:28: virtual memory exhausted
make[2]: *** [item_func.o] Error 1
@end example

Versuchen Sie, @code{ulimit -v 80000} zu benutzen, und lassen Sie
@code{make} erneut laufen. Wenn das nicht funktioniert und Sie @code{bash}
benutzen, versuchen Sie, statt dessen @code{csh} oder @code{sh} zu
benutzen. Einige BSDI-Benutzer haben Probleme mit @code{bash} und
@code{ulimit} berichtet.

Wenn Sie @code{gcc} benutzen, müssen Sie eventuell auch den
@code{--with-low-memory}-Flag für @code{configure} benutzen, um in der Lage
zu sein, @file{sql_yacc.cc} zu kompilieren.

Wenn Sie Probleme mit dem aktuellen Datum in MySQL erhalten, wird das
Setzen der @code{TZ}-Variablen das wahrscheinlich beheben.
@xref{Environment variables}.

@node BSDI3, BSDI4, BSDI2, BSD Notes
@c German node BSDI3
@subsubsection Anmerkungen zu BSD/OS Version 3.x

Aktualisieren Sie auf BSD/OS Version 3.1. Wenn das nicht möglich ist,
installieren Sie BSDI-Patch M300-038.

Benutzen Sie zur Konfiguration von MySQL folgenden Befehl:

@example
shell> env CXX=shlicc++ CC=shlicc2 \
       ./configure \
           --prefix=/usr/local/mysql \
           --localstatedir=/var/mysql \
           --without-perl \
           --with-unix-socket-path=/var/mysql/mysql.sock
@end example

Folgendes funktioniert bekanntermaßen ebenfalls:

@example
shell> env CC=gcc CXX=gcc CXXFLAGS=-O3 \
       ./configure \
           --prefix=/usr/local/mysql \
           --with-unix-socket-path=/var/mysql/mysql.sock
@end example

Wenn Sie wollen, können Sie die Verzeichnisorte ändern oder aber die
Vorgabewerte benutzen, indem Sie einfach keine Speicherorte angeben.

Wenn Sie Performance-Probleme unter Hochlast bekommen, versuchen Sie die
@code{--skip-thread-priority}-Option für @code{mysqld}! Dies führt alle
Threads mit derselben Priorität aus. Auf BSDI-Version 3.1 gibt Ihnen das
bessere Performance (zumindest solange, bis BSDI ihren Thread-Scheduler in
Ordnung bringt).

Wenn Sie beim Kompilieren den Fehler @code{virtual memory exhausted}
erhalten, probieren Sie es mit @code{ulimit -v 80000} und lassen Sie
@code{make} noch einmal laufen. Wenn das nicht funktioniert und Sie
@code{bash} benutzen, versuchen Sie, statt dessen @code{csh} oder @code{sh}
zu benutzen. Einige BSDI-Benutzer haben Probleme mit @code{bash} und
@code{ulimit} berichtet.


@node BSDI4,  , BSDI3, BSD Notes
@c German node BSDI4
@subsubsection Anmerkungen zu BSD/OS Version 4.x

BSDI-Version 4.x hat einige auf Threads bezogene Bugs. Wenn Sie auf dieser
Plattform MySQL benutzen wollen, sollten Sie alle Patches installieren, die
sich auf Threads beziehen. Zumindest M400-023 sollte installiert sein.

Auf einigen Systemen mit BSDI-Version 4.x bekommen Sie vielleicht Probleme
mit gemeinsam verwendeten (shared) Bibliotheken. Das äußert sich darin,
dass Sie keinerlei Client-Programme wie @code{mysqladmin} ausführen können.
In diesem Fall müssen Sie MySQL so rekonfigurieren, dass keine gemeinsam
genutzten Bibliotheken benutzt werden, indem Sie die
@code{--disable-shared}-Option für configure benutzen.

Einige Kunden hatten auf BSDI 4.0.1 Probleme damit, dass die
@code{mysqld}-Binärdatei nach einiger Zeit keine Tabellen mehr öffnen
konnte. Das liegt an einigen Bugs, die sich auf Bibliothek / System
beziehen, und die @code{mysqld} veranlassen, das aktuelle Verzeichnis zu
wechseln, ohne danach gefragt zu haben!

Die Lösung besteht darin, entweder auf 3.23.34 zu aktualisieren oder nach
dem Laufenlassen von @code{configure} die Zeile @code{#define
HAVE_REALPATH} aus @code{config.h} zu entfernen, bevor Sie make laufen
lassen.

Beachten Sie, dass sich aus dem Gesagten ergibt, dass Sie auf BSDI keine
symbolischen Links von Datenbankverzeichnissen zu einem anderen
Datenbankverzeichnis oder symbolische Links von einer Tabelle zu einer
anderen Datenbank herstellen können! (Ein symbolischer Link auf eine andere
Platte ist okay.)


@node Mac OS X, Other Unix Notes, BSD Notes, Operating System Specific Notes
@c German node Mac OS X
@subsection Anmerkungen zu Mac OS X



@menu
* Mac OS X Public Beta::        
* Mac OS X Server::             
@end menu

@node Mac OS X Public Beta, Mac OS X Server, Mac OS X, Mac OS X
@c German node Mac OS X Public Beta
@subsubsection Mac OS X Public Beta

MySQL sollte ohne jedes Problem auf Mac OS X Public Beta (Darwin) laufen.
Die pThread-Patches für dieses Betriebssystem benötigen Sie nicht!


@node Mac OS X Server,  , Mac OS X Public Beta, Mac OS X
@c German node Mac OS X Server
@subsubsection Mac OS X Server

Bevor Sie versuchen, MySQL auf Mac OS X Server zu konfigurieren, müssen Sie
das pThread-Paket von @uref{http://www.prnet.de/RegEx/mysql.html}
installieren.

Unsere Binärdatei für Mac OS X wird kompiliert auf Rhapsody 5.5, mit
folgender Konfigurationszeile:

@example
CC=gcc CFLAGS="-O2 -fomit-frame-pointer" CXX=gcc CXXFLAGS="-O2 -fomit-frame-pointer" ./configure --prefix=/usr/local/mysql "--with-comment=Official MySQL binary" --with-extra-charsets=complex  --disable-shared
@end example

Wenn Sie der Ressourcen-Datei Ihrer Shell Aliase hinzufügen wollen, um auf
@code{mysql} und @code{mysqladmin} von der Kommandozeile aus zuzugreifen,
geben Sie ein:

@example
alias mysql '/usr/local/mysql/bin/mysql'
alias mysqladmin '/usr/local/mysql/bin/mysqladmin'
@end example


@node Other Unix Notes, OS/2, Mac OS X, Operating System Specific Notes
@c German node Andere Unixe
@subsection Anmerkungen zu anderen Unixen



@menu
* Binary notes-HP-UX::          
* HP-UX 10.20::                 
* HP-UX 11.x::                  
* IBM-AIX::                     
* SunOS::                       
* Alpha-DEC-UNIX::              
* Alpha-DEC-OSF1::              
* SGI-Irix::                    
* Caldera::                     
* Caldera Unixware::            
@end menu

@node Binary notes-HP-UX, HP-UX 10.20, Other Unix Notes, Other Unix Notes
@c German node Binary notes-HP-UX
@subsubsection Anmerkungen zu HP-UX Notes für Binärdistributionen

@cindex HP-UX, Binärdistribution
@cindex Binärdistributionen, auf HP-UX

Einige Binärdistributionen von MySQL für HP-UX werden als HP-Depot-Datei
und als Tar-Datei ausgeliefert. Um die Depot-Datei benutzen zu können,
müssen Sie mindestens HP-UX 10.x haben, um auf HP's Software-Depot-Werkzeuge
zugreifen zu können.

Die HP-Version von MySQL wurde auf einem HP 9000/8xx-Server unter HP-UX
10.20 kompiliert und benutzt MIT-pThreads. Unter dieser Konfiguration
arbeitet sie bekanntermaßen gut. MySQL-Version 3.22.26 und neuer kann auch
mit HP's nativem Thread-Paket gebaut werden.

Weitere Konfigurationen, die ebenfalls funktionieren können:

@itemize @bullet
@item
HP 9000/7xx mit HP-UX 10.20+
@item
HP 9000/8xx mit HP-UX 10.30
@end itemize

Folgende Konfigurationen werden fast mit Sicherheit nicht laufen:

@itemize @bullet
@item
HP 9000/7xx oder 8xx mit HP-UX 10.x, wobei x < 2
@item
HP 9000/7xx oder 8xx mit HP-UX 9.x
@end itemize

Um die Distribution zu installieren, benutzen Sie die unten stehenden
Befehle, wobei @code{/pfad/zum/depot} der volle Pfadname der Depot-Datei
ist:

@itemize @bullet
@item
Um alles inklusive Server, Client- und Entwicklungs-Werkzeuge zu installieren:

@example
shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.full
@end example

@item
Um nur den Server zu installieren:

@example
shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.server
@end example

@item
Um nur das Client-Paket zu installieren:

@example
shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.client
@end example

@item
Um nur die Entwicklungs-Werkzeuge zu installieren:

@example
shell> /usr/sbin/swinstall -s /pfad/zum/depot mysql.developer
@end example
@end itemize

Das Depot speichert Binärdateien und Bibliotheken in @file{/opt/mysql} und
Daten in @file{/var/opt/mysql}. Es legt auch die entsprechenden Einträge in
@file{/etc/init.d} und @file{/etc/rc2.d} an, um den Server automatisch beim
Hochfahren zu starten. Das setzt @code{root}-Rechte zum Installieren
voraus.

Um die HP-UX-tar.gz-Distribution zu installieren, müssen Sie GNU @code{tar}
haben.


@node HP-UX 10.20, HP-UX 11.x, Binary notes-HP-UX, Other Unix Notes
@c German node HP-UX 10.20
@subsubsection Anmerkungen zu HP-UX Version 10.20

Es gibt einige kleine Probleme, wenn Sie MySQL auf HP-UX kompilieren. Wir
empfehlen, anstelle des nativen HP-UX-Kompilers @code{gcc} zu benutzen,
weil @code{gcc} besseren Code produziert!

Wir empfehlen die Benutzung von gcc 2.95 auf HP-UX. Benutzen Sie keine
hohen Optimierungs-Flags (wie -O6), weil das eventuell für HP-UX nicht
sicher ist.

Beachten Sie, dass MIT-pThreads nicht mit dem HP-UX-Kompiler kompiliert
werden können, weil dieser keine @code{.S}-(Assembler)-Dateien kompilieren
kann.

Folgende Konfigurationszeile sollte funktionieren:

@example
CFLAGS="-DHPUX -I/opt/dce/include" CXXFLAGS="-DHPUX -I/opt/dce/include -felide-constructors -fno-exceptions -fno-rtti" CXX=gcc ./configure --with-pThread --with-named-Thread-libs='-ldce' --prefix=/usr/local/mysql --disable-shared
@end example

Wenn Sie @code{gcc} 2.95 selbst kompilieren, sollten Sie ihn NICHT mit den
DCE-Bibliotheken (@code{libdce.a} oder @code{libcma.a}) linken, wenn Sie
MySQL mit MIT-pThreads kompilieren wollen. Wenn Sie DCE- und
MIT-pThreads-Pakete mischen, erhalten Sie einen @code{mysqld}, mit dem Sie
sich nicht verbinden können. Entfernen Sie die DCE-Bibliotheken, während
Sie @code{gcc} 2.95 kompilieren!


@node HP-UX 11.x, IBM-AIX, HP-UX 10.20, Other Unix Notes
@c German node HP-UX 11.x
@subsubsection Anmerkungen zu HP-UX Version 11.x

Für HP-UX Version 11.x empfehlen wir MySQL-Version 3.23.15 oder später.

Wegen einiger kritischer Bugs in den Standard-HP-UX-Bibliotheken sollten
Sie folgende Patches installieren, bevor Sie MySQL auf HP-UX 11.0 laufen
lassen:

@example
PHKL_22840 Streams cumulative
PHNE_22397 ARPA cumulative
@end example

Das löst das Problem, dass man @code{EWOULDBLOCK} von @code{recv()} 
und @code{EBADF} von @code{accept()} in threaded Applikationen erhält.

Wenn Sie @code{gcc} 2.95.1 auf einem nicht-gepatchten HP-UX-11.x-System
benutzen, erhalten Sie den Fehler:

@example
In file included by /usr/include/unistd.h:11,
                 by ../include/global.h:125,
                 by mysql_priv.h:15,
                 by item.cc:19:
/usr/include/sys/unistd.h:184: declaration of C function ...
/usr/include/sys/pThread.h:440: previous declaration ...
In file included by item.h:306,
                 by mysql_priv.h:158,
                 by item.cc:19:
@end example

Das Problem liegt darin, dass HP-UX @code{pThreads_atfork()} nicht
konsistent definiert. Es hat konfliktbehaftete Prototypes in
@file{/usr/include/sys/unistd.h}:184 und
@file{/usr/include/sys/pThread.h}:440 (Details weiter unten).

Eine Lösung besteht darin, @file{/usr/include/sys/unistd.h} nach
@file{mysql/include} zu kopieren und @file{unistd.h} zu editieren, wobei es
so abgeändert wird, dass es der Definition in @file{pThread.h} entspricht.
Hier ist der Diff:

@example
183,184c183,184
<      extern int pThread_atfork(void (*prepare)(), void (*parent)(),
<                                                void (*child)());
---
>      extern int pThread_atfork(void (*prepare)(void), void (*parent)(void),
>                                                void (*child)(void));
@end example

Danach sollte folgende Konfigurationszeile funktionieren:

@example
CFLAGS="-fomit-frame-pointer -O3 -fpic" CXX=gcc CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -O3" ./configure --prefix=/usr/local/mysql --disable-shared
@end example

Hier sind ein paar Informationen über das Kompilieren von MySQL mit dem
HP-UX:x-Kompiler, die uns ein Benutzer der HP-UX-Version 11.x geschickt
hat:

@example
 Environment:
      proper compilers.
         setenv CC cc
         setenv CXX aCC
      flags
         setenv CFLAGS -D_REENTRANT
         setenv CXXFLAGS -D_REENTRANT
         setenv CPPFLAGS -D_REENTRANT
     % aCC -V
     aCC: HP ANSI C++ B3910B X.03.14.06
     % cc -V /tmp/empty.c
     cpp.ansi: HP92453-01 A.11.02.00 HP C Preprocessor (ANSI)
     ccom: HP92453-01 A.11.01.00 HP C Compiler
     cc: "/tmp/empty.c", line 1: warning 501: Empty source file.

  configuration:
     ./configure  --with-pThread        \
     --prefix=/source-control/mysql     \
     --with-named-Thread-libs=-lpThread \
     --with-low-memory

    added '#define _CTYPE_INCLUDED' to include/m_ctype.h. This
    symbol ist the one defined in HP's /usr/include/ctype.h:

     /* Don't include std ctype.h when this is included */
     #define _CTYPE_H
     #define __CTYPE_INCLUDED
     #define _CTYPE_INCLUDED
     #define _CTYPE_USING   /* Don't put names in global namespace. */
@end example

@itemize @bullet
@item
Ich muss den Compile-Time-Flag @code{-D_REENTRANT} benutzen, um den
Kompiler dazu zu bringen, den Prototype für @code{localtime_r} zu erkennen.
Alternativ hätte ich auch den Prototype für @code{localtime_r} bereit
stellen können. Aber ich wollte weitere Bugs abfangen, in die ich sonst
gerannt wäre. Ich war nicht sicher, wo ich es benötigen würde, daher fügte
ich es zu allen Flags hinzu.
@item
Die Optimierungs-Flags, die MySQL benutzt (-O3), werden von den
HP-Kompilern nicht erkannt. Ich habe die Flags nicht geändert.
@end itemize

Wenn Sie folgenden Fehler von @code{configure} erhalten:

@example
checking for cc option to accept ANSI C... no
configure: error: MySQL requires a ANSI C compiler (and a C++ compiler). Try gcc. See the installation chapter in the reference manual.
@end example

Überprüfen Sie, dass Sie den Pfad zum K&R-Kompiler nicht vor dem Pfad zum
HP-UX-C- und C++-Kompiler haben.


@node IBM-AIX, SunOS, HP-UX 11.x, Other Unix Notes
@c German node IBM-AIX
@subsubsection Anmerkungen zu IBM-AIX

@cindex Probleme, Installation auf IBM-AIX

Automatische Erkennung von @code{xlC} fehlt bei Autoconf, daher wird ein
@code{configure}-Befehl wie folgender benötigt, wenn Sie MySQL kompilieren
(dieses Beispiel benutzt den IBM-Kompiler):

@example
export CC="xlc_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192 "
export CXX="xlC_r -ma -O3 -qstrict -qoptimize=3 -qmaxmem=8192"
export CFLAGS="-I /usr/local/include"
export LDLFAGS="-L /usr/local/lib"
export CPPFLAGS=$CFLAGS
export CXXFLAGS=$CFLAGS

./configure --prefix=/usr/local \
		--localstatedir=/var/mysql \
		--sysconfdir=/etc/mysql \
		--sbindir='/usr/local/bin' \
		--libexecdir='/usr/local/bin' \
		--enable-thread-safe-client \
		--enable-large-files
@end example

Das sind die Optionen, die benutzt werden, um die MySQL-Distribution zu
kompilieren, die sich auf @uref{http://www-frec.bull.com/} befindet.

Wenn Sie in obiger Konfigurationszeile @code{-O3} zu @code{-O2} ändern,
müssen Sie auch die @code{-qstrict}-Option entfernen (das ist eine
Beschränkung im IBM-C-Kompiler).

Wenn Sie @code{gcc} oder @code{egcs} benutzen, um MySQL zu kompilieren,
@strong{MÜSSEN} Sie den @code{-fno-exceptions}-Flag benutzen, weil das
Exception-Handling in @code{gcc} / @code{egcs} nicht Thread-sicher ist!
(Das wurde mit @code{egcs} 1.1. getestet.) Es gibt auch ein paar bekannte
Probleme mit dem IBM-Assembler, die dazu führen können, dass schlechter
Code erzeugt wird, wenn er zusammen mit gcc benutzt wird.

Wir empfehlen folgende @code{configure}-Zeile für @code{egcs} und
@code{gcc 2.95} auf AIX:

@example
CC="gcc -pipe -mcpu=power -Wa,-many" \
CXX="gcc -pipe -mcpu=power -Wa,-many" \
CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti" \
./configure --prefix=/usr/local/mysql --with-low-memory
@end example

@code{-Wa,-many} ist notwendig, damit das Kompilieren gelingt. Das Problem
ist IBM bekannt, hat es aber nicht eilig, es zu beheben, weil ein
Workaround verfügbar ist. Wir wissen nicht, ob @code{-fno-exceptions} für
@code{gcc 2.95} erforderlich ist, aber weil MySQL keine Exceptions benutzt
und die obige Option schnelleren Code erzeugt, empfehlen wir, dass Sie
diese Option für @code{egcs / gcc} immer benutzen.

Wenn Sie ein Problem mit Assembler-Code bekommen, versuchen Sie, -mcpu=xxx
so anzupassen, dass es zu Ihrem Prozessor passt. Typischerweise wird man
power2, power oder powerpc benutzen, alternativ kann man eventuell 604 oder
604e benutzen. Ich bin nicht ganz sicher, aber ich würde sagen, dass
"power" meist sicher sein sollte, selbst auf einer power2-Maschine.

Wenn Sie nicht wissen, welchen Prozessor Sie haben, geben Sie "uname -m"
ein. Das gibt eine Zeichenkette zurück, die etwa wie "000514676700"
aussieht, mit dem Format xxyyyyyymmss, wobei xx und ss immer die Nullen
sind (0). yyyyyy ist eine eindeutige System-ID und mm ist die ID des
CPU-Planars. Eine Tabelle dieser Werte liegt auf
@uref{http://www.rs6000.ibm.com/doc_link/en_US/a_doc_lib/cmds/aixcmds5/uname.htm}.
Darin finden Sie Maschinentyp und Maschinenmodell, was Sie benutzen können,
um herauszufinden, welchen Prozessortyp Sie haben.

Wenn Sie Probleme mit Signalen haben (MySQL stirbt unerwartet unter hoher
Last), haben Sie vielleicht einen Betriebssystem-Bug bei Threads und
Signalen gefunden. In diesem Fall können Sie MySQL anweisen, keine Signale
zu benutzen, indem Sie es wie folgt konfigurieren:

@example
shell> CFLAGS=-DDONT_USE_THR_ALARM CXX=gcc \
       CXXFLAGS="-felide-constructors -fno-exceptions -fno-rtti -DDONT_USE_THR_ALARM" \
       ./configure --prefix=/usr/local/mysql --with-debug --with-low-memory
@end example

Das berührt nicht die Performance von MySQL, hat aber den Nebeneffekt, dass
Sie keine Clients auf einer Verbindung mit @code{mysqladmin kill} oder
@code{mysqladmin shutdown} killen können, die ``schlafen''. Statt dessen
wird der Client sterben, wenn er den nächsten Befehl sendet.

Bei einigen Versionen von AIX für das Linken mit @code{libbind.a} bei
@code{getservbyname} zu einem Speicherauszug (Core Dump). Das ist ein
AIX-Bug, der IBM berichtet werden sollte.

Bei AIX 4.2.1 und gcc müssen Sie folgende Änderungen durchführen:

Nach dem Konfigurieren müssen Sie @file{config.h} und
@file{include/my_config.h} editieren und die Zeile ändern, in der steht:

@example
#define HAVE_SNPRINTF 1
@end example

zu

@example
#undef HAVE_SNPRINTF
@end example

Schließlich müssen Sie in @file{mysqld.cc} einen Prototype für initgoups
hinzufügen:

@example
#ifdef _AIX41
extern "C" int initgroups(const char *,int);
#endif
@end example


@node SunOS, Alpha-DEC-UNIX, IBM-AIX, Other Unix Notes
@c German node SunOS
@subsubsection Anmerkungen zu SunOS 4

Auf SunOS 4 werden MIT-pThreads benötigt, um MySQL zu kompilieren, was
letztlich bedeutet, dass Sie GNU-@code{make} benötigen.

Einige SunOS-4-Systeme haben Probleme mit dynamischen Bibliotheken und
@code{libtool}. Sie können folgende @code{configure}-Zeile benutzen, um das
Problem zu vermeiden:

@example
shell> ./configure --disable-shared --with-mysqld-ldflags=-all-static
@end example

Wenn Sie @code{readline} kompilieren, erhalten Sie vielleicht Warnungen
über duplizierte Defines. Diese können ignoriert werden.

Wenn Sie @code{mysqld} kompilieren, gibt es ein paar @code{implicit
declaration of function}-Warnungen. Diese können ignoriert werden.


@node Alpha-DEC-UNIX, Alpha-DEC-OSF1, SunOS, Other Unix Notes
@c German node Alpha-DEC-UNIX
@subsubsection Anmerkungen zu Alpha-DEC-UNIX (Tru64)

Wenn Sie egcs 1.1.2 auf Digital Unix benutzen, sollten Sie auf gcc 2.95.2
aktualisieren, weil egcs auf DEC einige schwer wiegende Bugs hat!

Wenn Sie threaded Programme unter Digital Unix kompilieren, empfiehlt die
Dokumentation, die @code{-pThread}-Option für @code{cc} und @code{cxx} und
die Bibliotheken @code{-lmach -lexc} zu benutzen (zusätzlich zu
@code{-lpThread}). Sie sollten @code{configure} wie folgt laufen lassen:

@example
CC="cc -pThread" CXX="cxx -pThread -O" \
./configure --with-named-thread-libs="-lpThread -lmach -lexc -lc"
@end example

Wenn Sie @code{mysqld} kompilieren, sehen Sie eventuell eine Reihe von
Warnungen wie die folgende:

@example
mysqld.cc: In function void handle_connections()':
mysqld.cc:626: passing long unsigned int *' as argument 3 of
accept(int,sockadddr *, int *)'
@end example

Sie können diese Warnungen ignorieren. Sie treten auf, weil
@code{configure} nur Fehler entdecken kann, keine Warnungen.

Wenn Sie den Server direkt von the Kommandozeile starten, haben Sie
vielleicht Probleme, dass er stirbt, wenn Sie sich ausloggen. (Wenn Sie
sich ausloggen, erhalten Ihre offenen Prozesse ein @code{SIGHUP}-Signal.)
Wenn das der Fall ist, starten Sie den Server wie folgt:

@example
shell> nohup mysqld [options] &
@end example

@code{nohup} bewirkt, dass der folgende Befehl jegliche
@code{SIGHUP}-Signale, die vom Terminal gesendet werden, ignoriert.
Alternativ starten Sie den Server mit @code{safe_mysqld}, was @code{mysqld}
mit @code{nohup} für Sie aufruft.
@xref{safe_mysqld, , @code{safe_mysqld}}.

Wenn Sie ein Problem beim Kompilieren von mysys/get_opt.c bekommen,
entfernen Sie einfach die Zeile #define _NO_PROTO am Anfang dieser Datei!

Wenn Sie den CC-Kompiler von Compaq benutzen, sollte die folgende
Konfigurationszeile funktionieren:

@example
CC="cc -pThread"
CFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
CXX="cxx -pThread"
CXXFLAGS="-O4 -ansi_alias -ansi_args -fast -inline speed all -arch host"
export CC CFLAGS CXX CXXFLAGS
./configure \
--prefix=/usr/local/mysql \
--with-low-memory \
--enable-large-files \
--enable-shared=yes \
--with-named-Thread-libs="-lpThread -lmach -lexc -lc"
gnumake
@end example

Wenn Sie ein Problem mit libtool beim Kompilieren mit gemeinsam genutzten
(shared) Bibliotheken bekommen wie oben, wenn Sie @code{mysql} linken,
sollten Sie dies folgendermaßen umgehen können:

@example
cd mysql
/bin/sh ../libtool --mode=link cxx -pThread  -O3 -DDBUG_OFF \
-O4 -ansi_alias -ansi_args -fast -inline speed \
-speculate all \ -arch host  -DUNDEF_HAVE_GETHOSTBYNAME_R \
-o mysql  mysql.o readline.o sql_string.o completion_hash.o \
../readline/libreadline.a -lcurses \
../libmysql/.libs/libmysqlclient.so  -lm
cd ..
gnumake
gnumake install
Skripts/mysql_install_db
@end example


@node Alpha-DEC-OSF1, SGI-Irix, Alpha-DEC-UNIX, Other Unix Notes
@c German node Alpha-DEC-OSF1
@subsubsection Anmerkungen zu Alpha-DEC-OSF1

Wenn Sie Probleme beim Kompilieren haben und DEC @code{CC} und @code{gcc}
installiert sind, versuchen Sie, @code{configure} wie folgt laufen zu
lassen:

@example
CC=cc CFLAGS=-O CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql
@end example

Wenn Sie Probleme mit der @file{c_asm.h}-Datei bekommen, können Sie wie
folgt eine 'dummy'-@file{c_asm.h}-Datei erzeugen und benutzen:

@example
touch include/c_asm.h
CC=gcc CFLAGS=-I./include \
CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql
@end example

Beachten Sie, dass die im Folgenden beschriebenen Probleme mit dem
@code{ld}-Programm behoben werden können, indem Sie das neueste
DEC-(Compaq)-Patch-Kit herunterladen, und zwar von folgender Seite:
@uref{http://ftp.Support.compaq.com/public/unix/}.

Auf OSF1 V4.0D und Kompiler "DEC C V5.6-071 auf Digital Unix V4.0 (Rev.
878)" zeigt der Kompiler einige seltsame Verhaltensweisen (undefinierte
@code{asm}-Symbole). Ausserdem scheint @code{/bin/ld} beschädigt zu sein
(Probleme mit @code{_exit undefined}-Fehlern, die auftreten, wenn Sie
@code{mysqld} linken). Auf diesem System konnten wir MySQL mit folgender
@code{configure}-Zeile kompilieren, nachdem wir @code{/bin/ld} mit der
Version von OSF 4.0C ersetzt haben:

@example
CC=gcc CXX=gcc CXXFLAGS=-O3 ./configure --prefix=/usr/local/mysql
@end example

Beim Digital-Kompiler "C++ V6.1-029" sollte folgendes funktionieren:

@example
CC=cc -pThread
CFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host
CXX=cxx -pThread
CXXFLAGS=-O4 -ansi_alias -ansi_args -fast -inline speed -speculate all -arch host -noexceptions -nortti
export CC CFLAGS CXX CXXFLAGS
./configure --prefix=/usr/mysql/mysql --with-mysqld-ldflags=-all-static --disable-shared --with-named-thread-libs="-lmach -lexc -lc"
@end example

In einigen Versionen von OSF1 ist die @code{alloca()}-Funktion beschädigt.
Beheben Sie dies, indem Sie die Zeile in @file{config.h} entfernen, die
@code{'HAVE_ALLOCA'} definiert.

Die @code{alloca()}-Funktion kann ebenfalls einen falschen Prototyp in
@code{/usr/include/alloca.h} haben. Die Warnung, die hieraus resultiert,
kann ignoriert werden.

@code{configure} benutzt automatisch folgenden Thread-Bibliotheken:
@code{--with-named-thread-libs="-lpThread -lmach -lexc -lc"}.

Wenn Sie @code{gcc} benutzen, können Sie auch versuchen, @code{configure}
wie folgt laufen zu lassen:

@example
shell> CFLAGS=-D_PTHREAD_USE_D4 CXX=gcc CXXFLAGS=-O3 ./configure ....
@end example

Wenn Sie Probleme mit Signalen haben (MySQL stirbt unerwartet unter
Hochlast), haben Sie vielleicht einen Betriebssystem-Bug bei Threads und
Signalen gefunden. In diesem Fall können Sie MySQL anweisen, keine Signale
zu benutzen, indem Sie es wie folgt konfigurieren:

@example
shell> CFLAGS=-DDONT_USE_THR_ALARM \
       CXXFLAGS=-DDONT_USE_THR_ALARM \
       ./configure ...
@end example

Das berührt nicht die Performance von MySQL, hat aber den Nebeneffekt, dass
Sie keine Clients auf einer Verbindung mit @code{mysqladmin kill} oder
@code{mysqladmin shutdown} killen können, die ``schlafen''. Statt dessen
wird der Client sterben, wenn er den nächsten Befehl sendet.

Bei @code{gcc} 2.95.2 erhalten Sie wahrscheinlich folgenden
Kompilierfehler:

@example
sql_acl.cc:1456: Internal compiler error in `scan_region', at except.c:2566
Please submit a full bug report.
@end example

Um das zu beheben, wechseln Sie ins @code{sql}-Verzeichnis und machen ein
``Kopieren und Einfügen'' der letzten @code{gcc}-Zeile, ändern aber
@code{-O3} zu @code{-O0} (oder fügen @code{-O0} unmittelbar nach @code{gcc}
hinzu, falls Sie keine @code{-O}-Option auf Ihrer Kompilierzeile haben.)
Danach wechseln Sie einfach direkt zurück in oberste Verzeichnis und lassen
@code{make} noch einmal laufen.


@node SGI-Irix, Caldera, Alpha-DEC-OSF1, Other Unix Notes
@c German node SGI-Irix
@subsubsection Anmerkungen zu SGI Irix

Wenn Sie Irix-Version 6.5.3 oder neuer benutzen, kann @code{mysqld} nur
dann Threads erzeugen, wenn Sie ihn als Benutzer mit
@code{CAP_SCHED_MGT}-Zugriffsrechten (wie @code{root}) laufen lassen oder
dem @code{mysqld}-Server dieses Recht mit dem folgenden Befehl geben:

@example
shell> chcap "CAP_SCHED_MGT+epi" /opt/mysql/libexec/mysqld
@end example

Sie müssen eventuell in @file{config.h} einige Dinge umdefinieren, nachdem
Sie @code{configure} laufen gelassen haben und vor dem Kompilieren.

In einigen Irix-Implementationen ist die @code{alloca()}-Funktion
beschädigt. Wenn der @code{mysqld}-Server bei manchen
@code{SELECT}-Statements stirbt, entfernen Sie die Zeilen aus
@file{config.h}, die @code{HAVE_ALLOC} und @code{HAVE_ALLOCA_H} definieren.
Wenn @code{mysqladmin create} nicht funktioniert, entfernen Sie die Zeile
aus @file{config.h}, die @code{HAVE_READDIR_R} definiert. Eventuell müssen
Sie auch die @code{HAVE_TERM_H}-Zeile entfernen.

SGI empfiehlt, dass Sie alle Patches auf dieser Seite auf einmal
installieren:
http://Support.sgi.com/surfzone/patches/patchset/6.2_indigo.rps.html

Als absolutes Minimum sollten Sie das letzte Kernel-Rollup installieren,
das letzte @code{rld}-Rollup und das letzte @code{libc}-Rollup.

In jedem Fall brauchen Sie für die pThread-Unterstützung alle POSIX-Patches
auf dieser Seite:

@uref{http://Support.sgi.com/surfzone/patches/patchset/6.2_posix.rps.html}

Wenn Sie beim Kompilieren von @file{mysql.cc} etwa folgenden Fehler
erhalten:

@example
"/usr/include/curses.h", line 82: error(1084): invalid combination of type
@end example

Geben Sie folgendes im obersten Verzeichnis Ihres MySQL-Source-Trees ein:

@example
shell> extra/replace bool curses_bool < /usr/include/curses.h > include/curses.h
shell> make
@end example

Es wurden ausserdem Scheduling-Probleme berichtet. Wenn nur ein Thread
läuft, läuft alles recht langsam. Das können Sie vermeiden, indem Sie einen
weiteren Client-Starten. Daraus kann sich eine zwei- bis zehnfache
Geschwindigkeitssteigerung für den anderen Thread ergeben. Das liegt an
einem Problem mit Irix-Threads, das kaum zu verstehen ist. Eventuell müssen
Sie improvisieren, um eine Lösung zu finden, bis dies behoben ist.

Wenn Sie mit @code{gcc} kompilieren, können Sie folgenden
@code{configure}-Befehl benutzen:

@example
CC=gcc CXX=gcc CXXFLAGS=-O3 \
./configure --prefix=/usr/local/mysql --enable-thread-safe-client --with-named-thread-libs=-lpThread
@end example

Auf Irix 6.5.11 mit nativen Irix-C- und C++-Kompilern der Version 7.3.1.2
soll auch folgendes funktionieren:

@example
CC=cc CXX=CC CFLAGS='-O3 -n32 -TARG:platform=IP22 -I/usr/local/include \
-L/usr/local/lib' CXXFLAGS='-O3 -n32 -TARG:platform=IP22 \
-I/usr/local/include -L/usr/local/lib' ./configure --prefix=/usr/local/mysql \
--with-berkeley-db --with-innodb \
--with-libwrap=/usr/local --with-named-curses-libs=/usr/local/lib/libncurses.a
@end example


@node Caldera, Caldera Unixware, SGI-Irix, Other Unix Notes
@c German node SCO
@subsubsection Anmerkungen zu Caldera
@c German fixup: 2002-03-22 monty changed SCO -> Caldera in English manual

Die aktuelle Portierung wird auf ``sco3.2v5.0.4''-
und-``sco3.2v5.0.5''-Systemen getestet. Die Portierung auf ``sco 3.2v4.2''
ist ebenfalls weit fortgeschritten.

Momentan ist der empfohlene Kompiler auf OpenServer gcc 2.95.2. Damit
sollten Sie in der Lage sein, MySQL einfach durch folgendes zu kompilieren:

@example
CC=gcc CXX=gcc ./configure ... (options)
@end example

@enumerate
@item
Bei OpenServer 5.0.X müssen Sie GDS in Skunkware 95 (95q4c) benutzen. Das
ist deshalb notwendig, weil GNU-@code{gcc} 2.7.2 in Skunkware 97 kein
GNU-@code{as} hat. Sie können auch @code{egcs} 1.1.2 oder neuer benutzen
@uref{http://www.egcs.com/}. Wenn Sie @code{egcs} 1.1.2 benutzen, müssen
Sie folgenden Befehl eingeben:

@example
shell> cp -p /usr/include/pThread/stdtypes.h /usr/local/lib/gcc-lib/i386-pc-sco3.2v5.0.5/egcs-2.91.66/include/pThread/
@end example

@item
Sie brauchen die Portierung von GCC 2.5.x für dieses Produkt und das
Entwicklungssystem. Sie werden auf dieser Version von Caldera (SCO) Unix benötigt.
Sie können nicht lediglich das GCC-Dev-System benutzen.

@item
Sie sollten zuerst das FSU-PThreads-Paket holen und installieren. Dieses
finden Sie auf
@uref{http://www.cs.wustl.edu/~schmidt/ACE_wrappers/FSU-Threads.tar.gz}.
Sie finden ein vorkompiliertes Paket auf
@uref{http://www.mysql.com/downloads/SCO/FSU-Threads-3.5c.tar.gz}.

@item
FSU-PThreads kann mit SCO Unix 4.2 mit TCP/IP kompiliert werden. Oder mit
OpenServer 3.0 oder Open Desktop 3.0 (OS 3.0 ODT 3.0), mit installiertem
Caldera (SCO) Entwicklungssystem unter Benutzung einer guten Portierung von GCC 2.5.x
ODT oder OS 3.0. Hierbei brauchen Sie eine gute Portierung von GCC 2.5.x.
Ohne gute Portierung gibt es eine Menge Probleme. Die Portierung für dieses
Produkt erfordert das Caldera (SCO) Unix-Entwicklungssystem. Ohne dieses fehlen die
Bibliotheken und der Linker, die benötigt werden.

@item
Um FSU-PThreads auf Ihrem System zu bauen, tun Sie folgendes:

@enumerate a
@item
Lassen Sie @code{./configure} im @file{Threads/src}-Verzeichnis laufen und
wählen Sie die SCO-OpenServer-Option. Dieser Befehl kopiert
@file{Makefile.SCO5} nach @file{Makefile}.

@item
Lassen Sie @code{make} laufen.

@item
Um in das vorgabemäßige @file{/usr/include}-Verzeichnis zu installieren,
loggen Sie sich als Root ein und wechseln (@code{cd}) Sie in das
@file{thread/src}-Verzeichnis. Führen Sie dann @code{make install} aus.
@end enumerate

@item
Denken Sie daran, GNU @code{make} zu benutzen, wenn Sie MySQL machen.

@item
Wenn Sie @code{safe_mysqld} nicht als Root starten, erhalten Sie
wahrscheinlich nur die 110 offenen Dateien pro Prozess. @code{mysqld} macht
darüber in der Log-Datei einen Eintrag.

@item
Bei SCO 3.2V5.0.5 sollten Sie FSU-PThreads-Version 3.5c oder neuer
benutzen. Ausserdem sollten Sie gcc 2.95.2 oder neuer benutzen!

Folgender @code{configure}-Befehl sollte funktionieren:

@example
shell> ./configure --prefix=/usr/local/mysql --disable-shared
@end example

@item
Bei SCO 3.2V4.2 sollten Sie FSU-PThreads-Version 3.5c oder neuer benutzen.
Folgender @code{configure}-Befehl sollte funktionieren:

@example
shell> CFLAGS="-D_XOPEN_XPG4" CXX=gcc CXXFLAGS="-D_XOPEN_XPG4" \
       ./configure \
           --prefix=/usr/local/mysql \
           --with-named-thread-libs="-lgThreads -lsocket -lgen -lgThreads" \
           --with-named-curses-libs="-lcurses"
@end example

Möglicherweise bekommen Sie Probleme mit einigen Include-Dateien. In diesem
Fall finden Sie neue, SCO-spezifische Include-Dateien auf
@uref{http://www.mysql.com/downloads/SCO/SCO-3.2v4.2-includes.tar.gz}.
Entpacken Sie diese Datei ins @file{include}-Verzeichnis Ihres
MySQL-Source-Trees.
@end enumerate

Anmerkungen zur Caldera (SCO) Entwicklung:

@itemize @bullet
@item
MySQL kann FSU-PThreads automatisch erkennen und @code{mysqld} mit
@code{-lgThreads -lsocket -lgThreads} linken.

@item
@c Question: Good translation for "re-entrant"?
Die Caldera (SCO) Entwicklungsbibliotheken sind re-entrant in FSU-PThreads. Caldera
behauptet, dass seine Bibliotheken-Funktionen re-entrant sind, daher müssen
sie mit FSU-PThreads re-entrant sein. FSU-PThreads auf OpenServer versucht,
das SCO-Scheme zu benutzen, um Bibliotheken re-entrant zu machen.

@item
FSU-PThreads (zumindest die Version auf @uref{http://www.mysql.com/}) wird
mit gelinktem GNU-@code{malloc} ausgeliefert. Wenn Sie Problemen mit der
Speicherbenutzung begegnen, stellen Sie sicher, dass @file{gmalloc.o} in
@file{libgThreads.a} und @file{libgThreads.so} beinhaltet ist.

@item
In FSU-PThreads achten folgende Systemaufrufe auf pThreads: @code{read()},
@code{write()}, @code{getmsg()}, @code{connect()}, @code{accept()},
@code{select()} und @code{wait()}.
@end itemize

Wenn Sie DBI auf Caldera (SCO) installieren wollen, müssen Sie @file{Makefile} in
DBI-xxx und jedem Unterverzeichnis editieren.

Beachten Sie, dass folgendes gcc 2.95.2 oder neuer voraussetzt:

@example
ALT:                                  NEU:
CC = cc                               CC = gcc
CCCDLFLAGS = -KPIC -W1,-Bexport       CCCDLFLAGS = -fpic
CCDLFLAGS = -wl,-Bexport              CCDLFLAGS =

LD = ld                               LD = gcc -G -fpic
LDDLFLAGS = -G -L/usr/local/lib       LDDLFLAGS = -L/usr/local/lib
LDFLAGS = -belf -L/usr/local/lib      LDFLAGS = -L/usr/local/lib

LD = ld                               LD = gcc -G -fpic
OPTIMISE = -Od                        OPTIMISE = -O1

OLD:
CCCFLAGS = -belf -dy -w0 -U M_XENIX -DPERL_SCO5 -I/usr/local/include

NEW:
CCFLAGS = -U M_XENIX -DPERL_SCO5 -I/usr/local/include
@end example

Das liegt daran, dass der Perl-dynaloader keine @code{DBI}-Module lädt, die
mit @code{icc} oder @code{cc} kompiliert wurden.

Perl funktioniert am besten, wenn es mit @code{cc} kompiliert wird.


@node Caldera Unixware,  , Caldera, Other Unix Notes
@c German node SCO Unixware
@subsubsection Anmerkungen zu Caldera Unixware Version 7.0
@c German fixup: 2002-03-22 monty changed SCO -> Caldera in English manual

Sie benötigen mindestens MySQL-Version 3.22.13, weil diese Version einige
Portabilitätsprobleme unter Unixware behebt.

Wir waren in der Lage, MySQL mit folgendem @code{configure}-Befehl auf
Unixware Version 7.0.1 zu kompilieren:

@example
CC=cc CXX=CC ./configure --prefix=/usr/local/mysql
@end example

Wenn Sie @code{gcc} benutzen wollen, müssen Sie @code{gcc} 2.95.2 oder
neuer benutzen.




@node OS/2, BeOS, Other Unix Notes, Operating System Specific Notes
@c German node OS/2
@subsection Anmerkungen zu OS/2

MySQL benutzt eine ganze Menge offener Dateien. Deswegen sollten Sie Ihrer
@file{CONFIG.SYS}-Datei folgendes hinzufügen:

@example
SET EMXOPT=-c -n -h1024
@end example

Wenn Sie das nicht tun, erhalten Sie wahrscheinlich folgenden Fehler:

@example
File 'xxxx' not found (Errcode: 24)
@end example

Wenn Sie MySQL auf OS/2 Warp 3 einsetzen, wird FixPack 29 oder höher
benötigt. Bei OS/2 Warp 4 wird FixPack 4 oder höher benötigt. Das erfordert
die PThreads-Bibliothek. MySQL muss auf einer Partition installiert werden,
die lange Dateinamen unterstützt, also zum Beispiel HPFS, FAT32 usw.

Das @file{INSTALL.CMD}-Skript muss von OS/2's eigener @file{CMD.EXE} aus
laufen gelassen werden und funktioniert eventuell nicht mit Ersatz-Shells
wie @file{4OS2.EXE}.

Das @file{scripts/mysql-install-db}-Skript wurde umbenannt. Es heißt jetzt
@file{install.cmd} und ist ein REXX-Skript, welches die vorgabemäßigen
MySQL-Sicherheitseinstellungen einstellt und die WorkPlace-Shell-Icons für
MySQL erstellt.

Unterstützung für dynamische Module wird einkompiliert, ist aber noch nicht
komplett durchgetestet. Dynamische Module sollten unter Benutzung der
PThreads-Runtime-Bibliothek kompiliert werden.

@example
gcc -Zdll -Zmt -Zcrtdll=pthrdrtl -I../include -I../regex -I.. \
    -o example udf_example.cc -L../lib -lmysqlclient udf_example.def
mv example.dll example.udf
@end example

@strong{Beachten Sie:} Aufgrund von Beschränkungen in OS/2 dürfen
UDF-module-name-stems nicht länger als 8 Zeichen sein. Module werden im
@file{/mysql2/udf}-Verzeichnis gespeichert; das
@code{safe-mysqld.cmd}-Skript trägt dieses Verzeichnis in die
@code{BEGINLIBPATH}-Umgebungsvariable ein. Wenn Sie UDF-Module benutzen,
werden festgelegte Erweiterungen ignoriert - es wird nicht angenommen, dass
sie @file{.udf} sind.
Unter Unix zum Beispiel könnte das gemeinsam genutzte (shared) Module
@file{example.so} benannt sein. Sie würden daraus eine Funktion wie folgt
laden:

@example
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example.so";
@end example

Unter OS/2 würde das Modul @file{example.udf} heißen, aber Sie würden
nicht die Modul-Erweiterung angeben:

@example
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "example";
@end example


@node BeOS, Novell Netware, OS/2, Operating System Specific Notes
@c German node BeOS
@subsection Anmerkungen zu BeOS

Wir sind sehr daran interessiert, MySQL auf BeOS ans Laufen zu bringen,
aber leider kennen wir niemanden, der sich mit BeOS auskennt oder Zeit hat,
eine Portierung durchzuführen.

Wir sind daran interessiert, jemanden für eine Portierung zu finden, und
wir werden ihn / sie bei allen technischen Fragen helfen, die bei einer
Portierung auftreten können.

Wir haben vor einiger Zeit mit einigen BeOS-Entwicklern gesprochen, die uns
sagten, dass MySQL zu 80% auf BeOS portiert ist, aber wir haben schon eine
Weile nichts von ihnen gehört.


@node Novell Netware,  , BeOS, Operating System Specific Notes
@c German node Novell Netware
@subsection Anmerkungen zu Novell NetWare

Wir sind sehr daran interessiert, MySQL auf NetWare ans Laufen zu bringen,
aber leider kennen wir niemanden, der sich mit NetWare auskennt oder Zeit hat,
eine Portierung durchzuführen.

Wir sind daran interessiert, jemanden für eine Portierung zu finden, und
wir werden ihn / sie bei allen technischen Fragen helfen, die bei einer
Portierung auftreten können.

@node Perl support,  , Operating System Specific Notes, Installing
@c German node Perl-Unterstützung
@section Anmerkungen zur Perl-Installation

@cindex Perl, Installation
@cindex Installation, Perl

@code{DBI}/@code{DBD}-Schnittstelle


@menu
* Perl installation::           
* ActiveState Perl::            
* Windows Perl::                
* Perl support problems::       
@end menu

@node Perl installation, ActiveState Perl, Perl support, Perl support
@c German node Perl-Installation
@subsection Installation von Perl unter Unix

Perl-Unterstützung für MySQL wird durch die @code{DBI}/@code{DBD}-
Client-Schnittstelle zur Verfügung gestellt. @xref{Perl}. Der Perl-
@code{DBD}/@code{DBI}-Client-Code erfordert Perl Version 5.004 oder
später. Die Schnittstelle @strong{funktioniert nicht}, wenn Sie eine
ältere Version von Perl haben.

MySQL-Perl-Unterstützung erfordert ausserdem, dass Sie MySQL-Client-
Programmierunterstützung installiert haben. Wenn Sie MySQL von RPM-
Dateien installiert haben, sind Client-Programme im Client-RPM
enthalten, aber Client-Programmierunterstützung ist im Entwickler-RPM.
Stellen Sie sicher, dass Sie auch das letztgenannte RPM installiert
haben.

Ab Version 3.22.8 wird Perl-Unterstützung getrennt von der Haupt-MySQL-
Unterstützung ausgeliefert. Wenn Sie Perl-Unterstützung installieren
wollen, können Sie die benötigten Dateien von
@uref{http://www.mysql.com/Downloads/Contrib/} herunter laden.

Die Perl-Distributionen werden als komprimierte @code{tar}-Archive zur
Verfügung gestellt und haben Namen wie @file{MODULE-VERSION.tar.gz},
wobei @code{MODULE} der Modulname und @code{VERSION} die Versionsnummer
ist. Sie sollten die @code{Data-Dumper}-, @code{DBI}- und @code{Msql-
Mysql-modules}-Distributionen laden und sie in dieser Reihenfolge
installieren. Die Installationsprozedur ist unten dargestellt. Das
Beispiel gilt für das @code{Data-Dumper}-Modul, ist aber für alle drei
Distributionen dieselbe:

@enumerate
@item
Entpacken Sie die Distribution ins aktuelle Verzeichnis.
@example
shell> gunzip < Data-Dumper-VERSION.tar.gz | tar xvf -
@end example
Dieser Befehl erzeugt ein Verzeichnis namens @file{Data-Dumper-
VERSION}.

@item
Wechseln Sie ins oberste Verzeichnis der entpackten Distribution:
@example
shell> cd Data-Dumper-VERSION
@end example

@item
Bauen Sie die Distribution und kompilieren Sie alles:
@example
shell> perl Makefile.PL
shell> make
shell> make test
shell> make install
@end example
@end enumerate

Der @code{make test}-Befehl ist wichtig, weil er sicherstellt, dass die
Module funktionieren. Beachten Sie, dass der MySQL-Server während der
Befehlsausführung bei der @code{Msql-Mysql-modules}-Installation laufen
muss, um den Schnittstellen-Code auszuführen, den ansonsten schlägt der
Test fehl.

Es ist eine gute Idee, die @code{Msql-Mysql-modules}-Distribution neu zu
kompilieren und zu installieren, wenn Sie ein neues Release von MySQL
installieren, insbesondere, wenn Sie Symptome feststellen wie dass alle
Ihre @code{DBI}-Skripte einen Coredump liefern, nachdem Sie auf eine
höhere Version von MySQL aktualisiert haben.

Wenn Sie keine Rechte haben, die Perl-Module im Systemverzeichnis zu
installieren, oder wenn Sie lokale Perl-Module installieren wollen,
könnte Ihnen der folgende Link helfen:

@example
@uref{http://www.iserver.com/support/contrib/perl5/modules.html}
@end example

Suchen Sie nach der Überschrift
@code{Installing New Modules that Require Locally Installed Modules}.


@node ActiveState Perl, Windows Perl, Perl installation, Perl support
@c German node ActiveState-Perl
@subsection Installation von ActiveState-Perl unter Windows

@cindex Installation, Perl unter Windows
@cindex Perl, Installation unter Windows
@cindex ActiveState-Perl

Um das MySQL-@code{DBD}-Modul mit ActiveState-Perl unter Windows zu
installieren, gehen Sie wie folgt vor:

@itemize @bullet
@item 
Laden Sie ActiveState-Perl von 
@uref{http://www.activestate.com/Products/ActivePerl/}
und installieren Sie es.

@item
Öffnen Sie eine MS-DOS-Eingabeaufforderung.

@item 
Setzen Sie - falls erforderlich - die HTTP_proxy-Variable, zum Beispiel
wie folgt:

@example
set HTTP_proxy=my.proxy.com:3128
@end example

@item
Starten Sie das PPM-Programm: 

@example
C:\> c:\perl\bin\ppm.pl
@end example

@item
Falls noch nicht geschehen, installieren Sie @code{DBI}:

@example
ppm> install DBI
@end example

@item
Wenn das erfolgreich verlief, führen Sie folgenden Befehl aus:

@example
install
ftp://ftp.de.uu.net/pub/CPAN/authors/id/JWIED/DBD-mysql-1.2212.x86.ppd
@end example
@end itemize

Das sollte zumindest bei ActiveState-Perl Version 5.6 funktionieren.

Wenn Sie es nicht schaffen, dass oben Genanntes funktioniert, sollten
Sie statt dessen den @strong{MyODBC}-Treiber installieren und sich mit
dem MySQL-Server über ODBC verbinden:

@example
use DBI;
$dbh= DBI->connect("DBI:ODBC:$dsn","$user","$password") ||
  die "Fehler $DBI::errstr beim Verbinden mit $dsn\n";
@end example


@node Windows Perl, Perl support problems, ActiveState Perl, Perl support
@c German node Windows-Perl
@subsection Installation der MySQL-Perl-Distribution unter Windows

Die MySQL-Perl-Distribution enthält @code{DBI},
@code{DBD:MySQL} und @code{DBD:ODBC}.

@itemize @bullet
@item 
Laden Sie die Perl-Distribution für Windows von
@uref{http://www.mysql.com/download.html}.

@item
Entpacken Sie die Distribution in @code{C:}, so dass Sie ein
@file{C:\PERL}-Verzeichnis erhalten.

@item
Fügen Sie Ihrem Pfad @file{C:\PERL\BIN} hinzu.

@item
Fügen Sie Ihrem Pfad das Verzeichnis @file{C:\PERL\BIN\MSWIN32-x86-
thread} oder @file{C:\PERL\BIN\MSWIN32-x86} hinzu.

@item
Testen Sie, ob @code{perl} funktioniert, indem Sie @code{perl -v} in
einer MS-DOS-Eingabeaufforderung ausführen.
@end itemize


@node Perl support problems,  , Windows Perl, Perl support
@c German node Perl-Unterstützung Probleme
@subsection Probleme bei der Benutzung von Perl @code{DBI}/@code{DBD}-Schnittstelle

@cindex Probleme, Installation von Perl
@cindex Perl DBI/DBD, Installationsprobleme

Wenn Perl ausgibt, dass es das @file{../mysql/mysql.so}-Modul nicht
finden kann, liegt das Problem wahrscheinlich darin, dass Perl die
gemeinsam genutzte @file{libmysqlclient.so} nicht findet.

Das können Sie mit einer der folgenden Methoden beheben:

@itemize @bullet
@item
Kompilieren Sie die @code{Msql-Mysql-modules}-Distribution mit
@code{perl Makefile.PL -static -config} statt mit @code{perl
Makefile.PL}.

@item
Kopieren Sie @code{libmysqlclient.so} in das Verzeichnis, in dem Ihre
anderen gemeinsam genutzten Bibliotheken liegen (wahrscheinlich
@file{/usr/lib} oder @file{/lib}).

@item
Unter Linux können Sie der @file{/etc/ld.so.conf}-Datei den Pfadnamen
des Verzeichnisses hinzufügen, in dem @file{libmysqlclient.so} liegt.

@tindex LD_RUN_PATH-Umgebungsvariable
@tindex Umgebungsvariable, LD_RUN_PATH
@item
Fügen Sie der @code{LD_RUN_PATH}-Umgebungsvariablen den Pfadnamen des
Verzeichnisses hinzu, in dem @file{libmysqlclient.so} liegt.
@end itemize

Wenn Sie folgende Fehler von @code{DBD-mysql} erhalten, benutzen Sie
wahrscheinlich @code{gcc} (oder eine alte Binärdatei, die mit @code{gcc}
kompiliert wurde):

@example
/usr/bin/perl: can't resolve symbol '__moddi3'
/usr/bin/perl: can't resolve symbol '__divdi3'
@end example

Fügen Sie @code{-L/usr/lib/gcc-lib/... -lgcc} zum Link-Befehl hinzu,
wenn die @file{mysql.so}-Bibliothek gebaut wird (überprüfen Sie die
Ausgabe von @code{make} nach @file{mysql.so}, wenn Sie den Perl-Client
kompilieren). Die @code{-L}-Option sollte den Pfadnamen des
Verzeichnisses angeben, in dem @file{libgcc.a} auf Ihrem System liegt.

Ein weiterer Grund für dieses Problem kann sein, dass Perl und MySQL
nicht beide mit @code{gcc} kompiliert wurden. In diesem Fall können Sie
die fehlende Übereinstimmung (Mismatch) durch Kompilieren von beiden mit
@code{gcc} aufheben.

Wenn Sie folgende Fehler von @code{Msql-Mysql-modules} erhalten, wenn
Sie die Tests laufen lassen:

@example
t/00base............install_driver(mysql) failed: Can't load
'../blib/arch/auto/DBD/mysql/mysql.so' for module DBD::mysql:
../blib/arch/auto/DBD/mysql/mysql.so: undefined symbol: uncompress at
/usr/lib/perl5/5.00503/i586-linux/DynaLoader.pm line 169.
@end example

Bedeutet das, dass Sie die Kompressionsbibliothek (-lz) in die Link-
Zeile einschließen müssen. Das kann man durch folgende Änderung in der
Datei @file{lib/DBD/mysql/Install.pm} tun:

@example
$sysliblist .= " -lm";

ändern in

$sysliblist .= " -lm -lz";
@end example

Danach @strong{müssen} Sie 'make realclean' laufen lassen und danach mit
der Installation von Anfang an beginnen.

Wenn Sie das Perl-Modul auf einem System laufen lassen wollen, das
dynamisches Linken nicht unterstützt (wie Caldera/SCO), können Sie eine
statische Version von Perl erzeugen, die @code{DBI} und @code{DBD-mysql}
enthält. Das bringt man zum Laufen, indem man eine Version von Perl
erzeugt, in der der @code{DBI}-Code eingelinkt ist, und diese über das
aktuelle Perls installiert. Dann benutzen Sie diese, um eine Version von
Perl zu bauen, die zusätzlich den @code{DBD}-Code eingelinkt hat, und
installieren diese.

Unter Caldera (SCO) müssen folgende Umgebungsvariablen gesetzt sein:

@example
shell> LD_LIBRARY_PATH=/lib:/usr/lib:/usr/local/lib:/usr/progressive/lib
or
shell>
LD_LIBRARY_PATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
shell>
LIBPATH=/usr/lib:/lib:/usr/local/lib:/usr/ccs/lib:/usr/progressive/lib:/usr/skunk/lib
shell>
MANPATH=scohelp:/usr/man:/usr/local1/man:/usr/local/man:/usr/skunk/man:
@end example

Erzeugen Sie zuerst ein Perl, das ein statisch gelinktes @code{DBI}
enthält, indem Sie diese Befehle im Verzeichnis ausführen, in dem Ihre
@code{DBI}-Distribution liegt:

@example
shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl
@end example

Dann müssen Sie das neue Perl installieren. Die Ausgabe von @code{make
perl} zeigt den genauen @code{make}-Befehl an, den Sie für die
Installation ausführen müssen. Unter Caldera (SCO) ist das @code{make -f
Makefile.aperl inst_perl MAP_TARGET=perl}.

Benutzen Sie als nächstes dieses soeben erzeugte Perl, um ein weiteres
Perl zu erzeugen, dass auch ein statisch gelinktes @code{DBD::mysql}
enthält, indem Sie diese Befehle im Verzeichnis ausführen, in dem Ihre
@code{Msql-Mysql-modules}-Distribution liegt:

@example
shell> perl Makefile.PL -static -config
shell> make
shell> make install
shell> make perl
@end example

Zum Schluss müssen Sie dieses neue Perl installieren. Hierbei zeigt die
Ausgabe von @code{make perl} wiederum, welcher Befehl benutzt werden
muss.

@node Tutorial, MySQL Database Administration, Installing, Top
@c German node Tutorial
@chapter Einführung in MySQL: Ein MySQL-Tutorial

@cindex Tutorial
@c Question: Uh - what's a defined terminal monitor?
@cindex terminal monitor, defined
@c Question: Uh - what's that for the index?
@cindex monitor, terminal
@cindex Optionen, von MySQL


Dieses Kapitel enthält eine Einführung in MySQL in Form eines Tutorials.
Datei wird gezeigt, wie Sie das @code{mysql}-Client-Programm benutzen, um
eine einfache Datenbank zu erzeugen und zu benutzen. @code{mysql} (auch
``Terminal-Monitor'' oder einfach ``Monitor'' genannt) ist ein interaktives
Programm, mit dem Sie sich mit einem MySQL-Server verbinden, Anfragen
(Queries) absetzen und die Ergebnisse ansehen können. @code{mysql} kann
auch im Stapelbetrieb (Batch Mode) benutzt werden: Sie schreiben Ihre
Anfragen zuerst in eine Datei und veranlassen dann @code{mysql}, die
Inhalte dieser Datei auszuführen. Hier werden beide Möglichkeiten
beschrieben, @code{mysql} zu benutzen.

Sie können @code{mysql} mit der @code{--help}-Option aufrufen, um eine
Liste der Optionen zu sehen:

@example
shell> mysql --help
@end example

Dieses Kapitel setzt voraus, dass @code{mysql} auf Ihrer Maschine
installiert ist und dass ein MySQL-Server verfügbar ist, mit dem Sie sich
verbinden können. Wenn das nicht der Fall sein sollte, setzen Sie sich mit
Ihrem MySQL-Administrator in Verbindung. (Wenn @emph{Sie} der Administrator
sind, müssen Sie in anderen Abschnitten des Handbuchs nachsehen.)

Dieses Kapitel beschreibt den gesamten Prozess der Einrichtung und
Benutzung einer Datenbank. Wenn Sie lediglich wissen wollen, wie man auf
eine bereits existierende Datenbank zugreift, können Sie die Abschnitte
überspringen, die beschreiben, wie man eine Datenbank und die Tabellen, die
sie enthält, erzeugt.

Weil dieses Kapitel ein Tutorial ist, wurden notwendigerweise viele Details
ausgelassen. Sehen Sie in den relevanten Abschnitten dieses Handbuchs nach,
wenn Sie weitere Informationen zu den Themen suchen, die hier besprochen
werden.


@menu
* Connecting-disconnecting::    
* Entering queries::            
* Database use::                
* Getting information::         
* Examples::                    
* Batch mode::                  
* Twin::                        
* Apache::                      
@end menu

@node Connecting-disconnecting, Entering queries, Tutorial, Tutorial
@c German node Verbinden und Trennen
@section Verbindung zum Server herstellen und trennen

@cindex Verbinden, mit dem Server
@cindex Verbindung trennen, mit dem Server
@cindex Server, verbinden
@cindex Server, Verbindung trennen

Um sich zum Server zu verbinden, müssen Sie beim Aufruf von @code{mysql} in
der Regel einen MySQL-Benutzernamen und üblicherweise auch ein Passwort
angeben. Wenn der Server auf einer anderen Maschine als der läuft, von der
Sie sich einloggen, müssen Sie auch einen Hostnamen angeben. Setzen Sie
sich mit Ihrem Administrator in Verbindung, um herauszubekommen, welche
Verbindungsparameter Sie benutzen sollten (das heißt welchen Host,
welchen Benutzername und welches Passwort Sie verwenden sollen). Wenn Sie
die richtigen Parameter kennen, sollten Sie sich wie folgt verbinden
können:

@example
shell> mysql -h host -u user -p
Enter password: ********
@end example

@code{********} steht für Ihr Passwort. Geben Sie es ein, wenn @code{mysql}
@code{Enter password:} anzeigt.

Wenn das funktioniert hat, sehen Sie ein paar einführende Informationen,
gefolgt von der @code{mysql>}-Eingabeaufforderung:


@example
shell> mysql -h host -u user -p
Enter password: ********
Welcome to the MySQL monitor.  Commands end mit ; or \g.
Your MySQL connection id ist 459 to server version: 3.22.20a-log

Type 'help' for help.

mysql>
@end example

Die Eingabeaufforderung sagt Ihnen, dass @code{mysql} bereit für die
Eingabe von Befehlen ist.

Einige
Einige MySQL-Installationen erlauben Benutzern, sich als anonyme
(unbenannte) Benutzer mit dem Server auf dem lokalen Host zu verbinden.
Wenn das auf Ihrer Maschine der Fall ist, können Sie sich mit diesem Server
verbinden, indem Sie @code{mysql} ohne irgend welche Optionen aufrufen:

@example
shell> mysql
@end example

Nachdem Sie sich erfolgreich verbunden haben, können Sie die Verbindung
jederzeit trennen, indem Sie @code{QUIT} an der
@code{mysql>}-Eingabeaufforderung eingeben.

@example
mysql> QUIT
Bye
@end example

Sie können die Verbindung auch trennen, indem Sie STRG+D eingeben.

Die meisten Beispiele der folgenden Abschnitte setzen voraus, dass Sie mit
dem Server verbunden sind. Das wird durch @code{mysql>} angezeigt.


@node Entering queries, Database use, Connecting-disconnecting, Tutorial
@c German node Anfragen eingeben
@section Anfragen eingeben

@cindex Absetzen, Anfragen
@cindex Anfragen, absetzen
@cindex Eingeben, Anfragen

Stellen Sie sicher, dass Sie mit dem Server verbunden sind, wie im
vorherigen Abschnitt erörtert. Dadurch wird noch keine Datenbank
ausgewählt, mit der Sie arbeiten können, aber das ist in Ordnung. Hier ist
es erst einmal wichtiger, herauszufinden, wie Sie Anfragen (Queries)
absetzen, als direkt mit dem Erzeugen von Tabellen, dem Einladen von Daten
in diese und der Abfrage von Daten aus diesen zu beginnen. Dieser Abschnitt
beschreibt die grundlegenden Prinzipien der Befehlseingabe, indem etliche
Anfragen gezeigt werden, die Sie ausprobieren können, um sich mit der
Arbeitsweise von @code{mysql} vertraut zu machen.

Hier ist ein einfacher Befehl, der den Server bittet, Ihnen seine
Versionsnummer und das aktuelle Datum mitzuteilen. Geben Sie folgendes an
der @code{mysql>}-Eingabeaufforderung ein und drücken Sie die Eingabetaste:

@example
mysql> SELECT VERSION(), CURRENT_DATE;
+--------------+--------------+
| version()    | CURRENT_DATE |
+--------------+--------------+
| 3.22.20a-log | 1999-03-19   |
+--------------+--------------+
1 row in set (0.01 sec)
mysql>
@end example

Diese Anfrage erläutert verschiedene Dinge über @code{mysql}:

@itemize @bullet
@item
Ein Befehl besteht normalerweise aus einem SQL-Statement, gefolgt von einem
Semikolon. (Es gibt ein paar Ausnahmen, bei denen das Semikolon nicht
benötigt wird. @code{QUIT}, das vorher erwähnt wurde, stellt eine solche
Ausnahme dar. Wir kommen später noch zu anderen Ausnahmen.)

@item
Wenn Sie einen Befehl absetzen, sendet @code{mysql} ihn zum Server, der ihn
ausführt, und zeigt die Ergebnisse an. Danach wird eine neue
@code{mysql>}-Eingabeaufforderung angezeigt, um klar zu machen, dass es für
einen weiteren Befehl bereit ist.

@item
@code{mysql} zeigt die Ausgabe der Anfrage in Tabellenform an (Zeilen und
Spalten). Die erste Zeile enthält Spaltenüberschriften. Die folgenden
Zeilen sind die Ergebnisse der Anfrage. Normalerweise sind die
Spaltenüberschriften die Spaltennamen der Tabellen, die Sie abfragen. Wenn
Sie statt der Spaltennamen den Wert eines Ausdrucks abfragen (wie im
gezeigten Beispiel), beschriftet @code{mysql} die Spaltenüberschrift mit
dem Ausdruck selbst.

@item
@code{mysql} zeigt, wie viele Zeilen zurück gegeben wurden und wie lang die
Ausführung der Anfrage dauerte, was ihnen eine grobe Einschätzung der
Server-Performance ermöglicht. Diese Werte sind ungenau, weil sie die
Wanduhrzeit repräsentieren (und nicht die Prozessor- oder Maschinenzeit),
und weil sie von Faktoren wie der Serverlast und der Netzwerk-Wartezeit
beeinflusst werden. (Um uns kurz zu fassen, zeigen wir die ``rows in
set''-Zeile in den weiteren Beispielen dieses Kapitels nicht mehr an.)
@end itemize

Schlüsselwörter können in beliebiger Schreibweise (Groß und klein)
eingegeben werden. Folgende Anfragen sind gleichwertig:

@example
mysql> SELECT VERSION(), CURRENT_DATE;
mysql> select version(), current_date;
mysql> SeLeCt vErSiOn(), current_DATE;
@end example

Hier kommt eine weitere Anfrage. Sie zeigt, wie Sie @code{mysql} als
einfachen Rechner benutzen können:

@example
mysql> SELECT SIN(PI()/4), (4+1)*5;
+-------------+---------+
| SIN(PI()/4) | (4+1)*5 |
+-------------+---------+
|    0.707107 |      25 |
+-------------+---------+
@end example

Die bislang gezeigten Befehle sind relativ kurze, einzeilige Statements.
Sie können allerdings auch mehrfache Statements auf einer einzelnen Zeile
eingeben. Beenden Sie einfach jedes davon mit einem Semikolon:

@example
mysql> SELECT VERSION(); SELECT NOW();
+--------------+
| version()    |
+--------------+
| 3.22.20a-log |
+--------------+

+---------------------+
| NOW()               |
+---------------------+
| 1999-03-19 00:15:33 |
+---------------------+
@end example

Ein Befehl muss nicht auf einer einzelnen Zeile eingegeben werden, so dass
längere Befehle, die mehrere Zeilen erfordern, kein Problem darstellen.
@code{mysql} stellt anhand des beendenden Semikolons fest, wo Ihr Statement
endet, und nicht etwa anhand des Zeilenendes. (Mit anderen Worten
akzeptiert @code{mysql} Freiformat-Eingaben: Es sammelt Eingabezeilen,
führt sie aber solange nicht aus, bis es das Semikolon sieht.)

Hier ist ein einfaches Statement, auf mehrere Zeilen verteilt:

@example
mysql> SELECT
    -> USER()
    -> ,
    -> CURRENT_DATE;
+--------------------+--------------+
| USER()             | CURRENT_DATE |
+--------------------+--------------+
| joesmith@@localhost | 1999-03-18   |
+--------------------+--------------+
@end example

Sehen Sie, wie sich die Eingabeaufforderung von @code{mysql>} zu @code{->}
ändert, nachdem Sie die erste Zeile der Mehrzeilen-Anfrage eingegeben
haben. Auf diese Weise zeigt @code{mysql} an, dass es noch nicht das
komplette Statement gesehen hat und auf den Rest wartet. Die
Eingabeaufforderung ist Ihr Freund, denn sie stellt wertvolle Rückmeldungen
zur Verfügung. Wenn Sie diese Rückmeldungen nutzen, werden Sie immer dessen
gewahr sein, worauf @code{mysql} wartet.

Wenn Sie den Befehl, den Sie gerade eingeben, nicht ausführen wollen,
können Sie ihn mit @code{\c} abbrechen:

@example
mysql> SELECT
    -> USER()
    -> \c
mysql>
@end example

Beachten Sie auch hierbei die Eingabeaufforderung. Sie ändert sich zurück
zu @code{mysql>}, nachdem Sie @code{\c} eingegeben haben, und diese
Rückmeldung bedeutet, dass @code{mysql} für einen weiteren Befehl bereit
ist.

Folgende Tabelle zeigt alle Eingabeaufforderungen, denen Sie begegnen
können, und fasst zusammen, was sie über den Zustand von @code{mysql}
aussagen:

@cindex Eingabeaufforderungen, Bedeutungen
@multitable @columnfractions .10 .9
@item @strong{Eingabeaufforderung} @tab @strong{Bedeutung}
@item @code{mysql>}                @tab Bereit für den nächsten Befehl.
@item @code{@ @ @ @ ->}            @tab Wartet auf die nächste Zeile eines
mehrzeiligen Befehls.
@item @code{@ @ @ @ '>}            @tab Wartet auf die nächste Zeile und
fasst eine Zeichenkette zusammen, die mit einem Apostroph (@samp{'})
beginnt.
@item @code{@ @ @ @ ">}            @tab Wartet auf die nächste Zeile und
fasst eine Zeichenkette zusammen, die mit Anführungszeichen (@samp{"})
beginnt.
@end multitable

Mehrzeilige Statements passieren häufig aus Versehen, wenn Sie vorhaben,
einen Befehl auf einer einzelnen Zeile abzusetzen, aber das beendende
Semikolon vergessen. In diesem Fall wartet @code{mysql} auf weitere
Eingaben:

@example
mysql> SELECT USER()
    ->
@end example

Wenn so etwas passiert (Sie dachten, Sie hätten ein Statement eingegeben,
aber die einzige Antwort ist die @code{->}-Eingabeaufforderung), wartet
@code{mysql} höchstwahrscheinlich auf das Semikolon. Wenn Sie nicht darauf
achten, was Ihnen die Eingabeaufforderung mitteilen will, könnten Sie eine
ganze Weile herum sitzen, bevor Sie feststellen, was Sie tun müssen. Geben
Sie ein Semikolon ein, um das Statement zu vollenden, und @code{mysql} wird
es ausführen:

@example
mysql> SELECT USER()
    -> ;
+--------------------+
| USER()             |
+--------------------+
| joesmith@@localhost |
+--------------------+
@end example

Die @code{'>}- und @code{">}-Eingabeaufforderungen kommen bei der Sammlung
von Zeichenketten vor. In MySQL können Sie Zeichenketten wahlweise in
@samp{'}- oder @samp{"}-Zeichen eingeschlossen eingeben (zum Beispiel
@code{'hallo'} oder @code{"tschüß"}), und @code{mysql} läßt Sie auch
Zeichenketten eingeben, die sich über mehrere Zeilen erstrecken. Wenn Sie
eine @code{'>}- oder @code{">}-Eingabeaufforderung sehen, heißt das, dass
Sie eine Zeile eingegeben haben, die eine Zeichenkette enthält, die mit
@samp{'} oder @samp{"} beginnt, dass Sie aber noch nicht das entsprechende
beendende Zeichen (ebenfalls @samp{'} oder @samp{"}) eingegeben haben. Das
ist in Ordnung, wenn Sie tatsächlich eine mehrzeilige Zeichenkette
eingeben, aber wie wahrscheinlich ist das? Nicht sehr wahrscheinlich.
Wahrscheinlicher ist, dass die @code{'>}- und
@code{">}-Eingabeaufforderungen anzeigen, dass Sie versehentlich ein
@samp{'}- oder @samp{"}-Zeichen ausgelassen haben. Beispiel:

@example
mysql> SELECT * FROM meine_tabelle WHERE name = "Schmidt AND age < 30;
    ">
@end example

Wenn Sie dieses @code{SELECT}-Statement eingeben, dann EINGABE drücken und
auf das Ergebnis warten, wird nichts passieren. Statt sich zu fragen, warum
diese Anfrage so lange dauert, beachten Sie des Rätsels Lösung, die die
@code{">}-Eingabeaufforderung anzeigt. Sie sagt Ihnen, dass @code{mysql}
auf den Rest einer nicht beendeten Zeichenkette wartet. (Sehen Sie den
Fehler im Statement? Der Zeichenkette @code{"Schmidt} fehlt das zweite
Anführungszeichen.)

Was machen Sie in diesem Fall? Das einfachste ist, den Befehl abzubrechen.
Sie können jetzt allerdings nicht einfach @code{\c} eingeben, weil
@code{mysql} es als Teil der Zeichenkette interpretieren würde, die es
gerade sammelt! Geben Sie daher zuerst das schließende Anführungszeichen
ein, damit @code{mysql} weiß, dass die Zeichenkette zuende ist, und erst
danach @code{\c}:

@example
mysql> SELECT * FROM meine_tabelle WHERE name = "Schmidt AND age < 30;
    "> "\c
mysql>
@end example

Die Eingabeaufforderung ändert sich wieder zu @code{mysql>} und zeigt damit
an, dass @code{mysql} für einen weiteren Befehl bereit ist.

Es ist wichtig, die Bedeutung der @code{'>}- und
@code{">}-Eingabeaufforderungen zu kennen, denn wenn Sie versehentlich
eine nicht beendete Zeichenkette eingeben, werden alle folgenden Zeilen,
die Sie eingeben, von @code{mysql} ignoriert - inklusive einer Zeile, die
@code{QUIT} enthält! Das kann recht verwirrend sein, besonders dann, wenn
Sie nicht wissen, dass Sie das schließende Anführungszeichen eingeben
müssen, bevor Sie den aktuellen Befehl abbrechen können.


@node Database use, Getting information, Entering queries, Tutorial
@c German node Datenbankbenutzung
@section Eine Datenbank erzeugen und benutzen

@cindex Datenbanken, erzeugen
@cindex Datenbanken, benutzen
@cindex Erzeugen, Datenbanken


Jetzt, wo Sie wissen, wie Sie Befehle eingeben, ist es Zeit, auf eine
Datenbank zuzugreifen.

Nehmen wir an, Sie haben zuhause mehrere Haustiere (Ihre Menagerie) und Sie
wollen unterschiedliche Arten von Information über sie im Überblick
behalten. Das können Sie tun, indem Sie Tabellen erzeugen, die Ihre Daten
beinhalten, und die Sie mit den gewünschten Informationen füllen. Dann
können Sie verschiedene Arten von Fragen über Ihre Haustiere beantworten,
indem Sie Daten aus den Tabellen abrufen. Dieser Abschnitt zeigt Ihnen:

@itemize @bullet
@item
Wie Sie eine Datenbank erzeugen
@item
Wie Sie eine Tabelle anlegen
@item
Wie Sie Daten in die Tabelle laden
@item
Wie Sie auf unterschiedliche Weise Daten aus der Tabelle abfragen
@item
Wie Sie mehrere Tabellen benutzen
@end itemize

Die Menagerie-Datenbank wird (bewusst) einfach sein, aber man kann sich
leicht Situationen im echten Leben vorstellen, in denen ein ähnlicher Typ
von Datenbank benutzt werden könnte. Beispielsweise könnte ein Bauer eine
solche Datenbankbenutzung, um den Überblick über sein Vieh zu behalten,
oder ein Tierarzt, um seine Patientendaten im Griff zu haben. Sie finden
eine Menagerie-Distribution, die einige der benutzten Anfragen und
Beispielsdaten enthält, auf der MySQL-Website.
Sie finden die Distribution entweder unter
@uref{http://www.mysql.com/downloads/Contrib/Examples/menagerie.tar.gz,komprimiertes @code{tar}-Format}
oder unter
@uref{http://www.mysql.com/downloads/Contrib/Beispiele/menagerie.zip,Zip-Format}.

Benutzen Sie das @code{SHOW}-Statement, um herauszufinden, welche
Datenbanken zur Zeit auf dem Server existieren:

@example
mysql> SHOW DATABASES;
+----------+
| database |
+----------+
| mysql    |
| test     |
| tmp      |
+----------+
@end example

Die Liste der Datenbanken weicht wahrscheinlich von derjenigen auf Ihrer
Maschine ab, aber wahrscheinlich befinden sich die @code{mysql}- und
@code{test}-Datenbanken darunter. Die @code{mysql}-Datenbank ist notwendig,
weil darin die Zugriffsrechte für Benutzer gespeichert sind. Die
@code{test}-Datenbank ist meist als Arbeitsbereich zum Ausprobieren dabei.

Wenn die @code{test}-Datenbank existiert, versuchen Sie, darauf
zuzugreifen:

@example
mysql> USE test
database changed
@end example

Beachten Sie, dass @code{USE} - wie @code{QUIT} - kein Semikolon erfordert.
(Sie können solche Statements mit einem Semikolon beenden, wenn Sie wollen,
es schadet nicht.) Das @code{USE}-Statement ist auch auf andere Art
besonders: Es muss auf einer einzigen Zeile eingegeben werden.

Sie können die @code{test}-Datenbank für die folgenden Beispiele benutzen
(wenn Sie Zugriff darauf haben), aber alles, was Sie dort anlegen, kann von
jedem sonstigen, der Zugriff darauf hat, entfernt werden. Aus diesem Grund
sollten Sie besser Ihren MySQL-Administrator um Erlaubnis bitten, eine
eigene Datenbankbenutzung zu können. Nehmen wir an, Sie wollen Ihre
Datenbank @code{menagerie} nennen. Dafür muss der Administrator folgenden
Befehl eingeben:

@example
mysql> GRANT ALL ON menagerie.* TO ihr_mysql_name;
@end example

Wobei @code{ihr_mysql_name} der MySQL-Benutzername ist, der Ihnen
zugewiesen wurde.


@menu
* Creating database::           
* Creating tables::             
* Loading tables::              
* Retrieving data::             
@end menu

@node Creating database, Creating tables, Database use, Database use
@c German node Datenbank erzeugen
@subsection Eine Datenbank erzeugen und auswählen

@cindex Auswählen, Datenbanken
@cindex Datenbanken, auswählen

Wenn der Administrator für Sie eine Datenbank erzeugt, wenn er Ihre
Zugriffsrechte einträgt, können Sie sie unmittelbar benutzen. Ansonsten
müssen Sie sie selbst anlegen:

@example
mysql> CREATE DATABASE menagerie;
@end example

Unter Unix sind Datenbanknamen abhängig von der Groß-/Kleinschreibung (im
Gegensatz zu SQL-Schlüsselwörtern), daher müssen Sie sich auf Ihre
Datenbank immer mit @code{menagerie} beziehen, nicht mit @code{Menagerie},
@code{MENAGERIE} oder irgend einer anderen Variante. Dasselbe gilt für
Tabellennamen. (Unter Windows trifft diese Beschränkung nicht zu. Dennoch
muss man sich bei einer gegebenen Anfrage auf Datenbanken und Tabellen in
derselben Schreibweise beziehen.)

Das Erzeugen einer Datenbank wählt diese nicht zur Benutzung aus. Das
müssen Sie explizit tun. Um @code{menagerie} zur aktuell ausgewählten
Datenbank zu machen, benutzen Sie folgenden Befehl:

@example
mysql> USE menagerie
database changed
@end example

Ihre Datenbank muss nur einmal erzeugt werden, aber Sie müssen sie jedes
Mal zur Benutzung auswählen, wenn Sie eine @code{mysql}-Sitzung beginnen.
Das können Sie durch die Eingabe eines @code{USE}-Statements wie oben
beschrieben tun. Alternativ können Sie die Datenbank auf der Kommandozeile
auswählen, wenn Sie @code{mysql} aufrufen. Geben Sie einfach ihren Namen
nach den Verbindungsparametern ein, die Sie ansonsten eingeben müssen.
Beispiel:

@example
shell> mysql -h host -u user -p menagerie
Enter password: ********
@end example

Beachten Sie, dass @code{menagerie} auf der gezeigten Kommandozeile nicht
Ihr Passwort ist! Wenn Sie Ihr Passwort auf der Kommandozeile nach der
@code{-p}-Option eingeben wollen, müssen Sie das ohne Leerzeichen
dazwischen machen (beispielsweise als @code{-pmeinpasswort}, nicht als
@code{-p meinpasswort}). Es wird allerdings nicht empfohlen, das Passwort
auf der Kommandozeile einzugeben, denn dann kann es durch andere Benutzer,
die auf Ihrer Maschine eingeloggt sind, ausspioniert werden.


@node Creating tables, Loading tables, Creating database, Database use
@c German node Tabellen erzeugen
@subsection Eine Tabelle erzeugen

@cindex Tabellen, erzeugen
@cindex Erzeugen, Tabellen
Die Datenbank zu erzeugen ist leicht, aber bis jetzt ist sie noch leer, wie
Ihnen @code{SHOW TABLES} zeigt:

@example
mysql> SHOW TABLES;
Empty set (0.00 sec)
@end example

Der schwierigere Teil besteht darin, sich zu entscheiden, wie die Struktur
Ihrer Datenbank sein sollte: Welche Tabellen Sie benötigen und welche
Spalten in jeder Tabelle enthalten sein sollen.

Sie brauchen eine Tabelle, die für jedes Ihrer Haustiere einen Datensatz
enthält. Diese kann @code{pet}-Tabelle genannt werden, und sie sollte
zumindest den Namen jedes Tiers enthalten. Weil lediglich der Name nicht
besonders interessant ist, sollte die Tabelle weitere Informationen
enthalten. Wenn zum Beispiel mehr als eine Person in Ihrer Familie ein
Haustier hält, würden Sie den Namen des Besitzers jedes Haustiers auflisten
wollen. Ausserdem wollen Sie vielleicht ein paar grundlegende Informationen
wie Art und Geschlecht einfügen.

Was ist mit dem Alter? Diese Information könnte interessant sein, aber es
ist keine gute Idee, sie in der Datenbank zu speichern. Das Alter ändert
sich, wenn die Zeit vergeht, was bedeutet, dass Sie Ihre Datensätze oft
aktualisieren müssen. Statt dessen ist es besser, einen festen Wert wie das
Geburtsdatum zu speichern. Immer, wenn Sie dann das Alter benötigen,
berechnen Sie es als Differenz zwischen dem aktuellen Datum und dem
Geburtstag. MySQL stellt Funktionen für Datumsberechnungen zur Verfügung,
daher ist so etwas nicht schwer. Ausserdem hat die Speicherung von
Geburtsdaten anstelle von Alter weitere Vorteile:

@itemize @bullet
@item
Sie können die Datenbank für Aufgaben wie die Erzeugung einer Liste
bevorstehender Tier-Geburtstage benutzen. (Wenn Sie das etwas albern
finden, bedenken Sie, dass sich dieselbe Frage zum Beispiel bei einer
Geschäftsdatenbank stellt, um Kunden herauszufinden, denen Sie in Kürze
Geburtstagswünsche schicken wollen, also für die Computer-unterstützte
persönliche Note.)

@item
Sie können Altersberechnungen mit anderen Bezugsdaten als dem aktuellen
Datum durchführen. Wenn Sie das Sterbedatum speichern, können Sie zum
Beispiel leicht errechnen, wie alt ein Haustier war, als es starb.
@end itemize

Wahrscheinlich fallen Ihnen weitere Informationen ein, die sinnvoller Weise
in der @code{pet}-Tabelle gespeichert werden könnten. Für unser Beispiel
sollen die bisher identifizierten Informationen fürs Erste ausreichen:
Name, Besitzer, Art, Geschlecht, Geburtstag und Sterbetag.

Legen Sie mit einem @code{CREATE TABLE}-Statement das Layout Ihrer Tabelle
fest:

@example
mysql> CREATE TABLE pet (name VARCHAR(20), besitzer VARCHAR(20),
    -> art VARCHAR(20), geschlecht CHAR(1), geburtstag DATE, sterbetag DATE);
@end example

@code{VARCHAR} ist für die @code{name}-, @code{besitzer}- und
@code{art}-Spalten eine gute Wahl, weil die Spaltenwerte in der Länge
variieren werden. Diese Spalten müssen auch nicht alle gleich sein, also
@code{20} Zeichen lang. Sie können jede beliebige Länge zwischen @code{1}
und @code{255} wählen, was immer Ihnen vernünftig erscheint. (Wenn Sie eine
schlechte Wahl getroffen haben und sich später herausstellt, dass Sie eine
längere Spalte brauchen, stellt MySQL ein @code{ALTER TABLE}-Statement zur
Verfügung.)

Das Geschlecht der Tiere kann vielfältig dargestellt werden, zum Beispiel
als @code{"m"} und @code{"w"}, oder auch als @code{"männlich"} und
@code{"weiblich"}. Am einfachsten ist es, hierfür einzelne Zeichen wie
@code{"m"} und @code{"w"} zu verwenden.

Der @code{DATE}-Datentyp für @code{geburtstag} und @code{sterbetag} liegt
auf der Hand.

Nachdem Sie eine Tabelle angelegt haben, sollte @code{SHOW TABLES} auch
etwas zeigen:

@example
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| pet                 |
+---------------------+
@end example

Um sicherzustellen, dass Ihre Tabelle so wie erwartet angelegt wurde,
benutzen Sie das @code{DESCRIBE}-Statement:

@example
mysql> DESCRIBE pet;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| name       | varchar(20) | YES  |     | NULL    |       |
| besitzer   | varchar(20) | YES  |     | NULL    |       |
| art        | varchar(20) | YES  |     | NULL    |       |
| geschlecht | char(1)     | YES  |     | NULL    |       |
| geburtstag | date        | YES  |     | NULL    |       |
| sterbetag  | date        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
@end example

Sie können @code{DESCRIBE} jederzeit benutzen, zum Beispiel, wenn Sie die
Namen der Spalten Ihrer Tabelle vergessen haben oder von welchem Datentyp
sie sind.


@node Loading tables, Retrieving data, Creating tables, Database use
@c German node Tabellen füllen
@subsection Daten in Tabellen einladen

@cindex Einladen, Tabellen
@cindex Tabellen, Daten einladen
@cindex Daten, in Tabellen laden

Nachdem Sie Ihre Tabelle erzeugt haben, müssen Sie sie mit Daten füllen.
Hierfür sind die @code{LOAD DATA}- und @code{INSERT}-Statements nützlich.

Nehmen wir an, Sie haben Haustiere wie unten aufgeführt. (Achten Sie bei
den Datumsangaben bitte darauf, dass MySQL Daten im
@code{YYYY-MM-DD}-Format erwartet, was von dem Format abweichen kann, an
das Sie gewohnt sind.)

@multitable @columnfractions .16 .16 .16 .16 .16 .16
@item @strong{name} @tab @strong{besitzer} @tab @strong{art} @tab @strong{geschlecht} @tab @strong{geburtstag} @tab @strong{sterbetag}
@item Fluffy @tab Harold @tab Katze @tab w @tab 1993-02-04 @tab
@item Claws @tab Gwen @tab Katze @tab m @tab 1994-03-17 @tab
@item Buffy @tab Harold @tab Hund @tab w @tab 1989-05-13 @tab
@item Fang @tab Benny @tab Hund @tab m @tab 1990-08-27 @tab
@item Bowser @tab Diane @tab Hund @tab m @tab 1998-08-31 @tab 1995-07-29
@item Chirpy @tab Gwen @tab Vogel @tab w @tab 1998-09-11 @tab
@item Whistler @tab Gwen @tab Vogel @tab @tab 1997-12-09 @tab
@item Slim @tab Benny @tab Schlange @tab m @tab 1996-04-29 @tab
@end multitable

Weil Sie mit einer leeren Tabelle beginnen, ist eine einfache Möglichkeit,
diese mit Daten zu füllen, dass Sie eine Textdatei erzeugen, die eine Zeile
für jedes Ihrer Tiere enthält, und die Inhalte dieser Datei dann mit einem
einzigen Statement in die Tabelle laden.

Erzeugen Sie also eine Textdatei @file{pet.txt}, die einen Datensatz pro
Zeile enthält, mit Werten, die durch TAB-Zeichen getrennt sind, und zwar in
der Reihenfolge, in der die Spalten im @code{CREATE TABLE}-Statement
aufgeführt waren. Fehlende Werte (wie unbekanntes Geschlecht oder
Sterbedaten für Tiere, die noch leben) ersetzen Sie mit @code{NULL}-Werten.
Um das in Ihrer Textdatei darzustellen, nehmen Sie @code{\N}. Der Datensatz
für den Vogel Whistler zum Beispiel sieht wie folgt aus (wobei der Leerraum
zwischen den Werten ein einzelnes TAB-Zeichen darstellt):

@multitable @columnfractions .15 .15 .15 .15 .25 .15
@item @code{Whistler} @tab @code{Gwen} @tab @code{Vogel} @tab @code{\N} @tab @code{1997-12-09} @tab @code{\N}
@end multitable

Um die Textdatei @file{pet.txt} in die @code{pet}-Tabelle zu laden,
benutzen Sie folgenden Befehl:

@example
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
@end example

Sie können das Trennzeichen für die Spalten und das Zeichen für Zeilenende
im @code{LOAD DATA}-Statement explizit festlegen, wenn Sie wollen, aber
vorgabemäßig sind das das TAB-Zeichen und das Zeilenvorschub-Zeichen. Das
reicht für das Statement aus, um die Datei @file{pet.txt} korrekt
einzulesen.

Wenn Sie einzeln neue Datensätze hinzufügen wollen, ist das
@code{INSERT}-Statement nützlich. In seiner einfachsten Form geben Sie für
jede Spalte Werte an, in genau der Reihenfolge, in der die Spalten im
@code{CREATE TABLE}-Statement aufgeführt wurden. Nehmen wir an, dass Diane
einen neuen Hamster namens Puffball bekommt. Sie fügen einen neuen
Datensatz mittels @code{INSERT}-Statement wie folgt hinzu:

@example
mysql> INSERT INTO pet
    -> VALUES ('Puffball','Diane','Hamster','w','1999-03-30',NULL);
@end example

Beachten Sie, dass hierbei Zeichenketten- und Datumswerte in
Anführungszeichen stehen. Mit @code{INSERT} können Sie auch direkt
@code{NULL} einfügen, um einen fehlenden Wert darzustellen. Sie können
dafür nicht @code{\N} wie bei @code{LOAD DATA} verwenden.

Diesem Beispiel können Sie auch entnehmen, dass es einiger Tipparbeit
bedurft hätte, die anfänglichen Datensätze mit mehreren
@code{INSERT}-Statements einzufügen, statt hierfür ein einziges @code{LOAD
DATA}-Statement zu verwenden.


@node Retrieving data,  , Loading tables, Database use
@c German node Daten abrufen
@subsection Informationen aus einer Tabelle abfragen

@cindex Daten, abrufen
@cindex Tabellen, Daten abrufen
@cindex Abrufen, Daten aus Tabellen
@cindex Entladen, Tabellen


Das @code{SELECT}-Statement wird benutzt, um Informationen aus einer
Tabelle herauszuziehen. Die allgemeine Form des Statements ist:

@example
SELECT auszuwählende_spalten
FROM tabelle
WHERE gewünschte_bedingungen
@end example

@code{auszuwählende_spalten} bezeichnet, was Sie sehen wollen. Das kann
entweder eine Liste von Spalten sein oder @code{*}, um ``alle Spalten'' zu
bezeichnen. @code{tabelle} kennzeichnet die Tabelle, aus der Sie Spalten
abfragen wollen. Die @code{WHERE}-Klausel ist optional. Wenn sie vorhanden
ist, kennzeichnet @code{gewünschte_bedingungen} die Bedingungen, mit denen
die Zeilen übereinstimmen müssen, damit sie abgefragt werden.


@menu
* Selecting all::               
* Selecting rows::              
* Selecting columns::           
* Sorting rows::                
* Date calculations::           
* Working with NULL::           
* Pattern matching::            
* Counting rows::               
* Multiple tables::             
@end menu

@node Selecting all, Selecting rows, Retrieving data, Retrieving data
@c German node Alles auswählen
@subsubsection Alle Daten auswählen

Die einfachste Form von @code{SELECT} fragt alles aus einer Tabelle ab:

@example
mysql> SELECT * FROM pet;
+----------+----------+----------+------------+------------+------------+
| name     | besitzer | art      | geschlecht | geburtstag | sterbetag  |
+----------+----------+----------+------------+------------+------------+
| Fluffy   | Harold   | Katze    | w          | 1993-02-04 | NULL       |
| Claws    | Gwen     | Katze    | m          | 1994-03-17 | NULL       |
| Buffy    | Harold   | Hund     | w          | 1989-05-13 | NULL       |
| Fang     | Benny    | Hund     | m          | 1990-08-27 | NULL       |
| Bowser   | Diane    | Hund     | m          | 1998-08-31 | 1995-07-29 |
| Chirpy   | Gwen     | Vogel    | w          | 1998-09-11 | NULL       |
| Whistler | Gwen     | Vogel    | NULL       | 1997-12-09 | NULL       |
| Slim     | Benny    | Schlange | m          | 1996-04-29 | NULL       |
| Puffball | Diane    | Hamster  | w          | 1999-03-30 | NULL       |
+----------+----------+----------+------------+------------+------------+
@end example

Diese Form von @code{SELECT} ist nützlich, wenn Sie Ihre gesamte Tabelle
abfragen wollen, zum Beispiel, wenn Sie sich gerade mit einem anfänglichen
Satz Daten geladen haben. Wie das so passiert, zeigt die Ausgabe einen
Fehler auf: Bowser scheint gestorben zu sein, bevor er geboren wurde! In
den Original-Stammbaum-Papieren finden Sie, dass das korrekte Geburtsjahr
1989 ist, nicht 1998.

Es gibt eine ganze Reihe Möglichkeiten, das zu beheben:

@itemize @bullet
@item
Editieren Sie die Datei @file{pet.txt} und beheben Sie den Fehler. Leeren
Sie dann die Tabelle und laden Sie erneut Daten hinein, indem Sie zuerst
@code{DELETE} und dann @code{LOAD DATA} benutzen:

@example
mysql> SET AUTOCOMMIT=1;  # Für schnelles Neuerzeugen der Tabelle
mysql> DELETE FROM pet;
mysql> LOAD DATA LOCAL INFILE "pet.txt" INTO TABLE pet;
@end example

Wenn Sie das jedoch tun, müssen Sie die Daten für Puffball erneut eingeben.

@item
Den fehlerhaften Datensatz mit einem @code{UPDATE}-Statement in Ordnung
bringen:

@example
mysql> UPDATE pet SET geburtstag = "1989-08-31" WHERE name = "Bowser";
@end example
@end itemize

Wie gezeigt ist es einfach, eine ganze Tabelle abzufragen. Aber
typischerweise wird das selten gewünscht sein, besonders, wenn die Tabelle
Groß wird. Statt dessen werden Sie an der Antwort auf bestimmte Fragen
interessiert sein, wobei Sie ein paar Beschränkungen in Bezug auf die
Informationen, die Sie wollen, festlegen. Schauen wir uns einige
Auswahl-Anfragen an, hinsichtlich der Fragen in Bezug auf Ihre Haustiere,
die sie beantworten.


@node Selecting rows, Selecting columns, Selecting all, Retrieving data
@c German node Zeilen auswählen
@subsubsection Bestimmte Zeilen auswählen

@cindex Zeilen, auswählen
@cindex Tabellen, Zeilen auswählen

Sie können nur bestimmte Zeilen Ihrer Tabelle auswählen. Wenn Sie zum
Beispiel die Geburtstags-Änderung von Bowser überprüfen wollen, wählen Sie
Bowsers Datensatz wie folgt aus:

@example
mysql> SELECT * FROM pet WHERE name = "Bowser";
+--------+----------+---------+-------------+------------+------------+
| name   | besitzer | art     | geschlecht  | geburtstag | sterbetag  |
+--------+----------+---------+-------------+------------+------------+
| Bowser | Diane    | dog     | m           | 1989-08-31 | 1995-07-29 |
+--------+----------+---------+-------------+------------+------------+
@end example


Die Ausgabe bestätigt, dass das Jahr inzwischen korrekt als 1989, nicht
1998, eingetragen ist.

Vergleiche von Zeichenketten achten normalerweise nicht auf
Groß-/Kleinschreibung, daher können Sie den Namen als @code{"bowser"},
@code{"BOWSER"} usw. angeben. Das Anfrageergebnis wird dasselbe bleiben.

Sie können für jede Spalte Bedingungen festlegen, nicht nur für
@code{name}. Wenn Sie zum Beispiel wissen wollen, welche Tiere nach 1998
geboren wurden, formulieren Sie eine Bedingung für die
@code{geburtstag}-Spalte:

@example
mysql> SELECT * FROM pet WHERE geburtstag >= "1998-1-1";
+----------+----------+---------+-------------+------------+-----------+
| name     | besitzer | art     | geschlecht  | geburtstag | sterbetag |
+----------+----------+---------+-------------+------------+-----------+
| Chirpy   | Gwen     | Vogel   | w           | 1998-09-11 | NULL      |
| Puffball | Diane    | Hamster | w           | 1999-03-30 | NULL      |
+----------+----------+---------+-------------+------------+-----------+
@end example

Sie können Bedingungen kombinieren, um zum Beispiel weibliche Hunde
festzustellen:

@example
mysql> SELECT * FROM pet WHERE art = "Hund" AND geschlecht = "w";
+-------+-----------+---------+------------+------------+-----------+
| name  | besitzer  | art     | geschlecht | geburtstag | sterbetag |
+-------+-----------+---------+------------+------------+-----------+
| Buffy | Harold    | Hund    | w          | 1989-05-13 | NULL      |
+-------+-----------+---------+------------+------------+-----------+
@end example

Die vorherige Anfrage benutzt den logischen Operator @code{AND}. Es gibt
auch einen @code{OR}-Operator:

@example
mysql> SELECT * FROM pet WHERE art = "Schlange" OR art = "Vogel";
+----------+----------+---------+-------------+------------+-----------+
| name     | besitzer | art     | geschlecht  | geburtstag | sterbetag |
+----------+----------+---------+-------------+------------+-----------+
| Chirpy   | Gwen     | Vogel   | w           | 1998-09-11 | NULL      |
| Whistler | Gwen     | Vogel   | NULL        | 1997-12-09 | NULL      |
| Slim     | Benny    | Schlange| m           | 1996-04-29 | NULL      |
+----------+----------+---------+-------------+------------+-----------+
@end example

@code{AND} und @code{OR} können gemischt werden. Wenn Sie das tun, ist es
eine gute Idee, Klammern zu verwenden, um anzuzeigen, wie die Bedingungen
gruppiert werden sollen:

@example
mysql> SELECT * FROM pet WHERE (art = "Katze" AND geschlecht = "m")
    -> OR (art = "Hund" AND geschlecht = "w");
+-------+-----------+---------+-------------+------------+-----------+
| name  | besitzer  | art     | geschlecht  | geburtstag | sterbetag |
+-------+-----------+---------+-------------+------------+-----------+
| Claws | Gwen      | Katze   | m           | 1994-03-17 | NULL      |
| Buffy | Harold    | Hund    | w           | 1989-05-13 | NULL      |
+-------+-----------+---------+-------------+------------+-----------+
@end example


@node Selecting columns, Sorting rows, Selecting rows, Retrieving data
@c German node Spalten auswählen
@subsubsection Bestimmte Spalten auswählen

@cindex Spalten, auswählen
@cindex Tabellen, Spalten auswählen

Wenn Sie nicht ganze Zeilen Ihrer Tabelle sehen wollen, geben Sie einfach
die Spalten an, an denen Sie interessiert sind, getrennt durch Kommas. Wenn
Sie zum Beispiel wissen wollen, wann Ihre Tiere geboren wurden, wählen Sie
die @code{name}- und @code{geburtstag}-Spalten aus:

@example
mysql> SELECT name, geburtstag FROM pet;
+----------+------------+
| name     | geburtstag |
+----------+------------+
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Buffy    | 1989-05-13 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Puffball | 1999-03-30 |
+----------+------------+
@end example

Um herauszufinden, wem welches Haustier gehört, benutzen Sie diese Anfrage:

@example
mysql> SELECT besitzer FROM pet;
+----------+
| besitzer |
+----------+
| Harold   |
| Gwen     |
| Harold   |
| Benny    |
| Diane    |
| Gwen     |
| Gwen     |
| Benny    |
| Diane    |
+----------+
@end example

@findex DISTINCT
Beachten Sie jedoch, dass diese Anfrage einfach die @code{besitzer}-Spalte
jedes Datensatzes abfragt, wodurch mehrere von ihnen mehrfach erscheinen.
Um die Ausgabe zu minimieren, fragen Sie jeden eindeutigen Datensatz nur
einmal ab, indem Sie das Schlüsselwort @code{DISTINCT} verwenden:

@example
mysql> SELECT DISTINCT besitzer FROM pet;
+-----------+
| besitzer  |
+-----------+
| Benny     |
| Diane     |
| Gwen      |
| Harold    |
+-----------+
@end example

Sie können eine @code{WHERE}-Klausel verwenden, um die Auswahl von Zeilen
mit der Auswahl von Spalten zu kombinieren. Um zum Beispiel nur die
Geburtstage von Hunden und Katzen zu erhalten, benutzen Sie diese Anfrage:

@example
mysql> SELECT name, art, geburtstag FROM pet
    -> WHERE art = "Hund" OR art = "Katze";
+--------+---------+------------+
| name   | art     | geburtstag |
+--------+---------+------------+
| Fluffy | Katze   | 1993-02-04 |
| Claws  | Katze   | 1994-03-17 |
| Buffy  | Hund    | 1989-05-13 |
| Fang   | Hund    | 1990-08-27 |
| Bowser | Hund    | 1989-08-31 |
+--------+---------+------------+
@end example


@node Sorting rows, Date calculations, Selecting columns, Retrieving data
@c German node Zeilen sortieren
@subsubsection Zeilen sortieren

@cindex Zeilen, sortieren
@cindex sortieren, Tabellenzeilen
@cindex sortieren, Daten
@cindex Tabellen, Zeilen sortieren

Sie haben bei den vorherigen Beispielen vielleicht bemerkt, dass die
Ergebniszeilen in keiner bestimmten Reihenfolge angezeigt werden. Häufig
ist es jedoch einfacher, die Ausgabe der Anfrage zu überprüfen, wenn die
Zeilen auf sinnvolle Art sortiert werden. Um ein Ergebnis zu sortieren,
benutzen Sie die @code{ORDER BY}-Klausel.

Hier sind die Geburtstage der Haustiere, sortiert nach Geburtstag:

@example
mysql> SELECT name, geburtstag FROM pet ORDER BY geburtstag;
+----------+------------+
| name     | geburtstag |
+----------+------------+
| Buffy    | 1989-05-13 |
| Bowser   | 1989-08-31 |
| Fang     | 1990-08-27 |
| Fluffy   | 1993-02-04 |
| Claws    | 1994-03-17 |
| Slim     | 1996-04-29 |
| Whistler | 1997-12-09 |
| Chirpy   | 1998-09-11 |
| Puffball | 1999-03-30 |
+----------+------------+
@end example

Um in umgekehrter Reihenfolge zu sortieren, fügen Sie das @code{DESC}-
(descending) Schlüsselwort zum Namen der Spalte, die Sie sortieren wollen,
hinzu:

@example
mysql> SELECT name, geburtstag FROM pet ORDER BY geburtstag DESC;
+----------+------------+
| name     | geburtstag |
+----------+------------+
| Puffball | 1999-03-30 |
| Chirpy   | 1998-09-11 |
| Whistler | 1997-12-09 |
| Slim     | 1996-04-29 |
| Claws    | 1994-03-17 |
| Fluffy   | 1993-02-04 |
| Fang     | 1990-08-27 |
| Bowser   | 1989-08-31 |
| Buffy    | 1989-05-13 |
+----------+------------+
@end example

Sie können über mehrere Spalten sortieren. Um beispielsweise zuerst nach
der Art des Tieres und dann nach dem Geburtsdatum innerhalb der Tierart zu
sortieren (die jüngsten Tiere zuerst), benutzen Sie folgende Anfrage:

@example
mysql> SELECT name, art, geburtstag FROM pet ORDER BY art, geburtstag DESC;
+----------+----------+------------+
| name     | art      | geburtstag |
+----------+----------+------------+
| Chirpy   | Vogel    | 1998-09-11 |
| Whistler | Vogel    | 1997-12-09 |
| Claws    | Katze    | 1994-03-17 |
| Fluffy   | Katze    | 1993-02-04 |
| Fang     | Hund     | 1990-08-27 |
| Bowser   | Hund     | 1989-08-31 |
| Buffy    | Hund     | 1989-05-13 |
| Puffball | Hamster  | 1999-03-30 |
| Slim     | Schlange | 1996-04-29 |
+----------+----------+------------+
@end example

Beachten Sie, dass sich das @code{DESC}-Schlüsselwort nur auf die Spalte
bezieht, die unmittelbar davor steht (@code{geburtstag}). @code{art}-Werte
werden nach wie vor in aufsteigender Reihenfolge sortiert.


@node Date calculations, Working with NULL, Sorting rows, Retrieving data
@c German node Datumsberechnungen
@subsubsection Datumsberechnungen

@cindex Datumsberechnungen
@cindex Berechnungen, Datumswerte
@cindex Extrahieren, Datumswerte
@cindex Alter, berechnen

MySQL stellt etliche Funktionen zur Verfügung, mit denen Sie
Datumsberechnungen wie Altersberechnungen oder das Extrahieren von
Datumsteilen durchführen können.

Um festzustellen, wie alt jedes Ihrer Haustiere ist, berechnen Sie die
Differenz im Jahresanteil des aktuellen Datums und des Geburtstags und
subtrahieren eins, wenn das aktuelle Datum früher im Kalender erscheint als
das Geburtsdatum. Folgende Anfrage zeigt für jedes Haustier das
Geburtsdatum, das aktuelle Datum und das Alter in Jahren:

@example
mysql> SELECT name, geburtstag, CURRENT_DATE,
    -> (YEAR(CURRENT_DATE)-YEAR(geburtstag))
    -> - (RIGHT(CURRENT_DATE,5)<RIGHT(geburtstag,5))
    -> AS age
    -> FROM pet;
+----------+------------+--------------+------+
| name     | geburtstag | CURRENT_DATE | age  |
+----------+------------+--------------+------+
| Fluffy   | 1993-02-04 | 2001-08-29   |    8 |
| Claws    | 1994-03-17 | 2001-08-29   |    7 |
| Buffy    | 1989-05-13 | 2001-08-29   |   12 |
| Fang     | 1990-08-27 | 2001-08-29   |   11 |
| Bowser   | 1989-08-31 | 2001-08-29   |   11 |
| Chirpy   | 1998-09-11 | 2001-08-29   |    2 |
| Whistler | 1997-12-09 | 2001-08-29   |    3 |
| Slim     | 1996-04-29 | 2001-08-29   |    5 |
| Puffball | 1999-03-30 | 2001-08-29   |    2 |
+----------+------------+--------------+------+
@end example

Hier zieht @code{YEAR()} den Jahresanteil eines Datums heraus.
@code{RIGHT()} zieht die rechts stehenden fünf Zeichen heraus, die für den
@code{MM-DD}-Teil des Datums stehen. Der Teil in dem Ausdruck, der die
@code{MM-DD}-Werte vergleicht, wird zu 1 oder 0 ausgewertet, was die
Jahresdifferenz ein Jahr nach unten anpasst, wenn @code{CURRENT_DATE}
früher im Jahr erscheint als @code{geburtstag}. Der gesamte Ausdruck ist
als Überschrift etwas plump, daher wir ein Alias (@code{age}) benutzt, um
die Spaltenüberschrift etwas lesbarer zu machen.

Die Anfrage funktioniert, aber das Ergebnis könnte leichter überblickt
werden, wenn die Zeilen in einer bestimmten Reihenfolge angezeigt würden.
Das kann man erreichen, indem man eine @code{ORDER BY name}-Klausel
hinzufügt, um die Ausgabe nach Namen zu sortieren:

@example
mysql> SELECT name, geburtstag, CURRENT_DATE,
    -> (YEAR(CURRENT_DATE)-YEAR(geburtstag))
    -> - (RIGHT(CURRENT_DATE,5)<RIGHT(geburtstag,5))
    -> AS age
    -> FROM pet ORDER BY name;
+----------+------------+--------------+------+
| name     | geburtstag | CURRENT_DATE | age  |
+----------+------------+--------------+------+
| Bowser   | 1989-08-31 | 2001-08-29   |   11 |
| Buffy    | 1989-05-13 | 2001-08-29   |   12 |
| Chirpy   | 1998-09-11 | 2001-08-29   |    2 |
| Claws    | 1994-03-17 | 2001-08-29   |    7 |
| Fang     | 1990-08-27 | 2001-08-29   |   11 |
| Fluffy   | 1993-02-04 | 2001-08-29   |    8 |
| Puffball | 1999-03-30 | 2001-08-29   |    2 |
| Slim     | 1996-04-29 | 2001-08-29   |    5 |
| Whistler | 1997-12-09 | 2001-08-29   |    3 |
+----------+------------+--------------+------+
@end example

Um die Ausgabe nach Alter (@code{age}) statt nach @code{name} zu sortieren,
benutzen Sie einfach eine andere @code{ORDER BY}-Klausel:

@example
mysql> SELECT name, geburtstag, CURRENT_DATE,
    -> (YEAR(CURRENT_DATE)-YEAR(geburtstag))
    -> - (RIGHT(CURRENT_DATE,5)<RIGHT(geburtstag,5))
    -> AS age
    -> FROM pet ORDER BY age;
+----------+------------+--------------+------+
| name     | geburtstag | CURRENT_DATE | age  |
+----------+------------+--------------+------+
| Chirpy   | 1998-09-11 | 2001-08-29   |    2 |
| Puffball | 1999-03-30 | 2001-08-29   |    2 |
| Whistler | 1997-12-09 | 2001-08-29   |    3 |
| Slim     | 1996-04-29 | 2001-08-29   |    5 |
| Claws    | 1994-03-17 | 2001-08-29   |    7 |
| Fluffy   | 1993-02-04 | 2001-08-29   |    8 |
| Fang     | 1990-08-27 | 2001-08-29   |   11 |
| Bowser   | 1989-08-31 | 2001-08-29   |   11 |
| Buffy    | 1989-05-13 | 2001-08-29   |   12 |
+----------+------------+--------------+------+
@end example


Eine ähnliche Anfrage kann benutzt werden, um das Alter am Sterbetag bei
Tieren festzustellen, die gestorben sind. Das können Sie feststellen, indem
Sie überprüfen, ob der @code{sterbetag}-Wert @code{NULL} ist. Dann
berechnen Sie für diejenigen Tiere mit Nicht-@code{NULL}-Werten den
Unterschied zwischen @code{sterbetag}- und @code{geburtstag}-Werten:

@example
mysql> SELECT name, geburtstag, sterbetag,
    -> (YEAR(sterbetag)-YEAR(geburtstag)) - (RIGHT(sterbetag,5)<RIGHT(geburtstag,5))
    -> AS age
    -> FROM pet WHERE sterbetag IS NOT NULL ORDER BY age;
+--------+------------+------------+------+
| name   | geburtstag | sterbetag  | age  |
+--------+------------+------------+------+
| Bowser | 1989-08-31 | 1995-07-29 |    5 |
+--------+------------+------------+------+
@end example

Die Anfrage benutzt @code{sterbetag IS NOT NULL} statt @code{sterbetag !=
NULL}, weil @code{NULL} ein spezieller Wert ist. Das wird später erklärt.
@xref{Working with NULL,  , Mit @code{NULL}-Werten arbeiten}.

Was ist, wenn Sie wissen wollen, welche Tiere nächsten Monat Geburtstag
haben? Für diese Art von Berechnung sind Jahre und Tage irrelevant. Sie
wollen lediglich den Monatsanteil der @code{geburtstag}-Spalte extrahieren.
MySQL bietet etliche Funktionen für die Extraktion von Datumsanteilen, wie
@code{YEAR()}, @code{MONTH()} und @code{DAYOFMONTH()}. @code{MONTH()} ist
hier die richtige Funktion. Um festzustellen, wie sie funktioniert, geben
Sie eine Anfrage ein, die sowohl die Werte von @code{geburtstag} als auch
die von @code{MONTH(geburtstag)} ausgibt:

@example
mysql> SELECT name, geburtstag, MONTH(geburtstag) FROM pet;
+----------+------------+-------------------+
| name     | geburtstag | MONTH(geburtstag) |
+----------+------------+-------------------+
| Fluffy   | 1993-02-04 |                 2 |
| Claws    | 1994-03-17 |                 3 |
| Buffy    | 1989-05-13 |                 5 |
| Fang     | 1990-08-27 |                 8 |
| Bowser   | 1989-08-31 |                 8 |
| Chirpy   | 1998-09-11 |                 9 |
| Whistler | 1997-12-09 |                12 |
| Slim     | 1996-04-29 |                 4 |
| Puffball | 1999-03-30 |                 3 |
+----------+------------+-------------------+
@end example

Tiere mit Geburtstagen im kommenden Monat zu finden ist ebenfalls leicht.
Nehmen wir an, der aktuelle Monat ist April. Dann ist der Monatswert
@code{4} und Sie suchen nach Tieren, die im Mai (Monat 5) geboren sind, wie
folgt:

@example
mysql> SELECT name, geburtstag FROM pet WHERE MONTH(geburtstag) = 5;
+-------+------------+
| name  | geburtstag |
+-------+------------+
| Buffy | 1989-05-13 |
+-------+------------+
@end example

Ein bisschen komplizierter ist es, wenn der aktuelle Monat Dezember ist.
Hier können Sie nicht einfach eins zur Monatszahl (@code{12}) hinzufügen,
weil es keinen 13. Monat gibt. Statt dessen suchen Sie nach Tieren, die im
Januar (Monat 1) geboren sind.

Sie können die Anfrage sogar so schreiben, dass sie unabhängig davon
funktioniert, was der aktuelle Monat ist. Auf diese Art brauchen Sie keine
bestimmte Monatszahl in der Anfrage benutzen. @code{DATE_ADD()} erlaubt
Ihnen, einem gegebenen Datum ein Zeitintervall hinzuzufügen. Wenn Sie dem
Wert von @code{NOW()} einen Monat hinzufügen und dann den Monatsanteil mit
@code{MONTH()} extrahieren, ergibt das den Monat, der die kommenden
Geburtstage enthält:

@example
mysql> SELECT name, geburtstag FROM pet
    -> WHERE MONTH(geburtstag) = MONTH(DATE_ADD(NOW(), INTERVAL 1 MONTH));
@end example

Eine andere Möglichkeit, diese Aufgabe zu erfüllen, ist, @code{1} zu
addieren, um den nächsten Monat nach dem aktuellen zu erhalten (nach
Gebrauch der Modulo-Funktion (@code{MOD}), um den Monatswert auf @code{0}
zu stellen, falls er aktuell @code{12}) ist:

@example
mysql> SELECT name, geburtstag FROM pet
    -> WHERE MONTH(geburtstag) = MOD(MONTH(NOW()), 12) + 1;
@end example

@code{MONTH} gibt eine Zahl zwischen 1 und 12 zurück.
@code{MOD(irgendwas,12)} gibt eine Zahl zwischen 0 und 11 zurück. Daher
muss die Addition nach @code{MOD()} erfolgen, weil wir ansonsten von
November (11) bis Januar (1) gehen würden.


@node Working with NULL, Pattern matching, Date calculations, Retrieving data
@c German node Mit NULL arbeiten
@subsubsection Mit @code{NULL}-Werten arbeiten

@findex NULL
@cindex NULL-Wert

Der @code{NULL}-Wert birgt Überraschungen, bis Sie mit ihm vertraut sind.
Konzeptionell bedeutet @code{NULL} einen fehlenden oder unbekannten Wert.
Er wird in einiger Hinsicht anders als andere Werte behandelt. Um auf
@code{NULL} zu testen, können Sie nicht die arithmetischen
Vergleichoperatoren wie @code{=}, @code{<} oder @code{!=} verwenden. Um
sich das zu veranschaulichen, probieren Sie folgenden Anfrage:

@example
mysql> SELECT 1 = NULL, 1 != NULL, 1 < NULL, 1 > NULL;
+----------+-----------+----------+----------+
| 1 = NULL | 1 != NULL | 1 < NULL | 1 > NULL |
+----------+-----------+----------+----------+
|     NULL |      NULL |     NULL |     NULL |
+----------+-----------+----------+----------+
@end example

Wie man sieht, erhält man aus diesen Vergleichen keine sinnvollen
Ergebnisse. Benutzen Sie statt dessen die @code{IS NULL}- und @code{IS NOT
NULL}-Operatoren:

@example
mysql> SELECT 1 IS NULL, 1 IS NOT NULL;
+-----------+---------------+
| 1 IS NULL | 1 IS NOT NULL |
+-----------+---------------+
|         0 |             1 |
+-----------+---------------+
@end example

In MySQL bedeutet 0 oder @code{NULL} logisch Falsch und alles sonstige
bedeutet logisch Wahr. Der vorgabemäßige Wahrheitswert einer Boolschen
Operation ist 1.

Diese besondere Behandlung von @code{NULL} ist der Grund, warum es im
vorherigen Abschnitt notwendig war, mit @code{sterbetag IS NOT NULL}
anstelle von @code{sterbetag != NULL} festzustellen, welche Tiere nicht
mehr leben.


@node Pattern matching, Counting rows, Working with NULL, Retrieving data
@c German node Suchmuster
@subsubsection Übereinstimmende Suchmuster

@cindex Übereinstimmende Suchmuster
@cindex Übereinstimmung, Suchmuster
@cindex Ausdrücke, erweitert

MySQL stellt Standard-SQL-Suchmuster-Übereinstimmung zur Verfügung, ebenso
wie eine Art der Suchmuster-Übereinstimmung, die auf regulären Ausdrücken
basiert, die denen ähnlich sind, die von Unix-Hilfsprogrammen wie
@code{vi}, @code{grep} und @code{sed} benutzt werden.

SQL-Suchmuster-Übereinstimmung gestattet Ihnen, @samp{_} zu benutzen, um
ein einzelnes Zeichen und @samp{%}, um eine beliebige Anzahl von Zeichen
(inklusive des 0-Zeichens) zu finden. In den MySQL-SQL-Suchmustern spielt
die Groß-/Kleinschreibung vorgabemäßig keine Rolle. Einige Beispiele sind
unten dargestellt. Beachten Sie, dass Sie @code{=} oder @code{!=} nicht
benutzen können, wenn Sie SQL-Suchmuster benutzen. Stattdessen müssen Sie
die @code{LIKE}- oder @code{NOT LIKE}-Vergleichsoperatoren benutzen.

So finden Sie Namen, die mit @samp{b} anfangen:

@example
mysql> SELECT * FROM pet WHERE name LIKE "b%";
+--------+----------+------+------------+------------+------------+
| name   | besitzer | art  | geschlecht | geburtstag | sterbetag  |
+--------+----------+------+------------+------------+------------+
| Buffy  | Harold   | Hund | w          | 1989-05-13 | NULL       |
| Bowser | Diane    | Hund | m          | 1989-08-31 | 1995-07-29 |
+--------+----------+------+------------+------------+------------+
@end example

So finden Sie Namen, die auf @samp{fy} enden:

@example
mysql> SELECT * FROM pet WHERE name LIKE "%fy";
+--------+----------+-------+------------+------------+-----------+
| name   | besitzer | art   | geschlecht | geburtstag | sterbetag |
+--------+----------+-------+------------+------------+-----------+
| Fluffy | Harold   | Katze | w          | 1993-02-04 | NULL      |
| Buffy  | Harold   | Hund  | w          | 1989-05-13 | NULL      |
+--------+----------+-------+------------+------------+-----------+
@end example

So finden Sie Namen, die @samp{w} enthalten:

@example
mysql> SELECT * FROM pet WHERE name LIKE "%w%";
+----------+----------+---------+-------------+------------+------------+
| name     | besitzer | art     | geschlecht  | geburtstag | sterbetag  |
+----------+----------+---------+-------------+------------+------------+
| Claws    | Gwen     | Katze   | m           | 1994-03-17 | NULL       |
| Bowser   | Diane    | Hund    | m           | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen     | bird    | NULL        | 1997-12-09 | NULL       |
+----------+----------+---------+-------------+------------+------------+
@end example

Um Namen zu finden, die genau fünf Zeichen enthalten, benutzen Sie das
@samp{_}-Suchmuster-Zeichen:

@example
mysql> SELECT * FROM pet WHERE name LIKE "_____";
+-------+----------+---------+-------------+------------+-----------+
| name  | besitzer | art     | geschlecht  | geburtstag | sterbetag |
+-------+----------+---------+-------------+------------+-----------+
| Claws | Gwen     | Katze   | m           | 1994-03-17 | NULL      |
| Buffy | Harold   | Hund    | w           | 1989-05-13 | NULL      |
+-------+----------+---------+-------------+------------+-----------+
@end example

Die andere Art von Suchmuster-Übereinstimmung benutzt erweiterte reguläre
Ausdrücke. Wenn Sie bei dieser Art von Suchmuster auf Übereinstimmung
prüfen, benutzen Sie die @code{REGEXP}- und @code{NOT REGEXP}-Operatoren
(oder @code{RLIKE} und @code{NOT RLIKE}, die synonym sind).

Einige Charakteristika erweiterter regulärer Ausdrücke sind:

@itemize @bullet
@item
@samp{.} findet jedes beliebige Zeichen.

@item
Eine Zeichenklasse @samp{[...]} findet jedes Zeichen innerhalb der
eckigen Klammern. So stimmt zum Beispiel @samp{[abc]} mit @samp{a},
@samp{b} oder @samp{c} überein. Um einen Bereich von Zeichen zu benennen,
benutzen Sie einen Bindestrich. @samp{[a-z]} stimmt mit jedem Buchstaben in
Kleinschreibung überein, wohingegen @samp{[0-9]} mit jeder Ziffer
übereinstimmt.

@item
@samp{*} stimmt mit null oder mehr Instanzen der Sache überein, die ihm
voransteht. @samp{x*} zum Beispiel stimmt mit einer beliebigen Anzahl von
@samp{x}-Zeichen überein. @samp{[0-9]*} stimmt mit einer beliebigen Anzahl
von Ziffern überein, und @samp{.*} mit jeder Anzahl von irgendetwas.

@item
Reguläre Ausdrücke achten auf Groß-/Kleinschreibung, aber Sie können eine
Zeichenklasse benutzen, um beide Schreibungen zu finden, wenn Sie wollen.
@samp{[aA]} zum Beispiel stimmt mit @samp{a} in Groß- und Kleinschreibung
überein und @samp{[a-zA-Z]} mit jedem Buchstaben in Groß- und
Kleinschreibung.

@item
Das Suchmuster stimmt überein, wenn es irgendwo in dem Wert auftaucht, der
überprüft wird. (SQL-Suchmuster stimmen nur überein, wenn sie mit dem
gesamten Wert übereinstimmen.)

@item
Um ein Suchmuster so zu verankern, dass er mit dem Anfang oder dem Ende des
überprüften Werts übereinstimmen muss, benutzen Sie @samp{^} am Anfang oder
@samp{$} am Ende des Suchmusters.
@end itemize

Um darzustellen, wie erweiterte reguläre Ausdrücke funktionieren, werden
die @code{LIKE}-Anfragen von oben noch einmal mit @code{REGEXP} gezeigt.

Um Namen zu finden, die mit @samp{b} anfangen, benutzen Sie @samp{^}, um
auf Übereinstimmung am Anfang des Namens zu prüfen:

@example
mysql> SELECT * FROM pet WHERE name REGEXP "^b";
+--------+-----------+---------+-------------+------------+------------+
| name   | besitzer  | art     | geschlecht  | geburtstag | sterbetag  |
+--------+-----------+---------+-------------+------------+------------+
| Buffy  | Harold    | Hund    | w           | 1989-05-13 | NULL       |
| Bowser | Diane     | Hund    | m           | 1989-08-31 | 1995-07-29 |
+--------+-----------+---------+-------------+------------+------------+
@end example

Vor MySQL-Version 3.23.4 achtet @code{REGEXP} auf Groß-/Kleinschreibung.
Daher gibt diese Anfrage ein Ergebnis ohne Zeilen zurück. Um sowohl Groß-
als auch Kleinschreibung von @samp{b} zu finden, benutzen Sie statt dessen
folgende Anfrage:

@example
mysql> SELECT * FROM pet WHERE name REGEXP "^[bB]";
@end example

Ab MySQL 3.23.4 müssen Sie, um die Beachtung der Groß-/Kleinschreibung in
einem @code{REGEXP}-Vergleich zu erzwingen, das @code{BINARY}-Schlüsselwort
verwenden, um eine der Zeichenketten zu einer binären Zeichenkette zu
machen. Diese Anfrage stimmt nur mit @samp{b} in Kleinschreibung am Anfang
eines Namens überein:

@example
mysql> SELECT * FROM pet WHERE name REGEXP BINARY "^b";
@end example

Um Namen zu finden, die auf @samp{fy} enden, benutzen Sie @samp{$}, um
Übereinstimmung am Ende des Namens zu finden:

@example
mysql> SELECT * FROM pet WHERE name REGEXP "fy$";
+--------+-----------+---------+-------------+------------+-----------+
| name   | besitzer  | art     | geschlecht  | geburtstag | sterbetag |
+--------+-----------+---------+-------------+------------+-----------+
| Fluffy | Harold    | Katze   | w           | 1993-02-04 | NULL      |
| Buffy  | Harold    | Hund    | w           | 1989-05-13 | NULL      |
+--------+-----------+---------+-------------+------------+-----------+
@end example

Um Namen zu finden, die @samp{w} in Groß- oder Kleinschreibung enthalten,
benutzen Sie diese Anfrage:

@example
mysql> SELECT * FROM pet WHERE name REGEXP "w";
+----------+----------+---------+-------------+------------+------------+
| name     | besitzer | art     | geschlecht  | geburtstag | sterbetag  |
+----------+----------+---------+-------------+------------+------------+
| Claws    | Gwen     | Katze   | m           | 1994-03-17 | NULL       |
| Bowser   | Diane    | Hund    | m           | 1989-08-31 | 1995-07-29 |
| Whistler | Gwen     | bird    | NULL        | 1997-12-09 | NULL       |
+----------+----------+---------+-------------+------------+------------+
@end example

Weil ein Suchmuster mit regulären Ausdrücken an beliebiger Stelle im Wert
gefunden wird, ist es bei der vorherigen Anfrage nicht notwendig, ein
Jokerzeichen (Wildcard) auf irgendeine Seite des Suchmusters zu setzen, um
nach Übereinstimmung im gesamten Wert zu suchen, wie es bei SQL-Suchmustern
der Fall sein müsste.

Um Namen zu finden, die genau fünf Zeichen enthalten, benutzen Sie @samp{^}
und @samp{$}, um mit Anfang und Ende des Namens Übereinstimmung zu finden,
und fünf Instanzen von @samp{.} dazwischen:

@example
mysql> SELECT * FROM pet WHERE name REGEXP "^.....$";
+-------+-----------+---------+-------------+------------+-----------+
| name  | besitzer  | art     | geschlecht  | geburtstag | sterbetag |
+-------+-----------+---------+-------------+------------+-----------+
| Claws | Gwen      | Katze   | m           | 1994-03-17 | NULL      |
| Buffy | Harold    | Hund    | w           | 1989-05-13 | NULL      |
+-------+-----------+---------+-------------+------------+-----------+
@end example

Sie könnten die vorherige Anfrage auch unter Verwendung des @samp{@{n@}}-
``wiederhole-@code{n}-mal''-Operators schreiben:

@example
mysql> SELECT * FROM pet WHERE name REGEXP "^.@{5@}$";
+-------+-----------+---------+-------------+------------+-----------+
| name  | besitzer  | art     | geschlecht  | geburtstag | sterbetag |
+-------+-----------+---------+-------------+------------+-----------+
| Claws | Gwen      | Katze   | m           | 1994-03-17 | NULL      |
| Buffy | Harold    | Hund    | w           | 1989-05-13 | NULL      |
+-------+-----------+---------+-------------+------------+-----------+
@end example


@node Counting rows, Multiple tables, Pattern matching, Retrieving data
@c German node Zeilen zählen
@subsubsection Zeilen zählen

@cindex Zeilen, zählen
@cindex Tabellen, Zeilen zählen
@cindex zählen, Tabellenzeilen

Datenbanken werden oft benutzt, um die Frage zu beantworten, wie oft eine
bestimmte Art von Daten in einer Tabelle erscheint. Sie wollen
beispielsweise wissen, wie viele Haustiere Sie haben, oder wie viele
Haustiere jeder Besitzer hat, oder Sie wollen verschiedene Arten von
Zählungen Ihrer Tiere durchführen.

Die Gesamtzahl der Tiere zählen, die Sie haben, ist dieselbe Frage wie
``Wie viele Zeilen sind in der @code{pet}-Tabelle?'', denn es gibt einen
Datensatz pro Haustier. Die @code{COUNT()}-Funktion zählt die Anzahl von
Nicht-@code{NULL}-Ergebnissen, daher lautet die Anfrage, um Ihre Tiere zu
zählen, wie folgt:

@example
mysql> SELECT COUNT(*) FROM pet;
+----------+
| COUNT(*) |
+----------+
|        9 |
+----------+
@end example

Sie haben vorher schon einmal die Namen der Leute abgefragt, die Haustiere
besitzen. Sie können @code{COUNT()} benutzen, wenn Sie herausfinden wollen,
wie viele Tiere jeder Besitzer hat:

@example
mysql> SELECT besitzer, COUNT(*) FROM pet GROUP BY besitzer;
+-----------+----------+
| besitzer  | COUNT(*) |
+-----------+----------+
| Benny     |        2 |
| Diane     |        2 |
| Gwen      |        3 |
| Harold    |        2 |
+-----------+----------+
@end example

Beachten Sie die Benutzung von @code{GROUP BY}, um alle Datensätze für
jeden @code{besitzer} zu gruppieren. Ohne das erhalten Sie eine
Fehlermeldung:

@example
mysql> SELECT besitzer, COUNT(besitzer) FROM pet;
ERROR 1140 at line 1: Mixing of GROUP columns (MIN(),MAX(),COUNT()...)
with no GROUP columns is illegal if there is no GROUP BY clause
@end example

@code{COUNT()} und @code{GROUP BY} sind nützlich, um Ihre Daten auf
verschiedene Weise zu charakterisieren. Die folgenden Beispiele zeigen
verschiedene Möglichkeiten, um Zählungen Ihrer Tiere durchzuführen.

Anzahl der Tiere pro Art:

@example
mysql> SELECT art, COUNT(*) FROM pet GROUP BY art;
+---------+----------+
| art     | COUNT(*) |
+---------+----------+
| Vogel   |        2 |
| Katze   |        2 |
| Hund    |        3 |
| Hamster |        1 |
| Schlange|        1 |
+---------+----------+
@end example

Anzahl der Tiere pro Geschlecht:

@example
mysql> SELECT geschlecht, COUNT(*) FROM pet GROUP BY geschlecht;
+-------------+----------+
| geschlecht  | COUNT(*) |
+-------------+----------+
| NULL        |        1 |
| w           |        4 |
| m           |        4 |
+-------------+----------+
@end example

(In dieser Ausgabe zeigt @code{NULL} an, dass das Geschlecht unbekannt
ist.)

Anzahl der Tiere pro Kombination von Art und Geschlecht:

@example
mysql> SELECT art, geschlecht, COUNT(*) FROM pet GROUP BY art, geschlecht;
+---------+-------------+----------+
| art     | geschlecht  | COUNT(*) |
+---------+-------------+----------+
| Vogel   | NULL        |        1 |
| Vogel   | w           |        1 |
| Katze   | w           |        1 |
| Katze   | m           |        1 |
| Hund    | w           |        1 |
| Hund    | m           |        2 |
| Hamster | w           |        1 |
| Schlange| m           |        1 |
+---------+-------------+----------+
@end example

Sie müssen nicht die gesamte Tabelle abfragen, wenn Sie @code{COUNT()}
benutzen. Die vorherige Anfrage beispielsweise sieht lediglich für Hunde
und Katzen wie folgt aus:

@example
mysql> SELECT art, geschlecht, COUNT(*) FROM pet
    -> WHERE art = "Hund" OR art = "Katze"
    -> GROUP BY art, geschlecht;
+---------+-------------+----------+
| art     | geschlecht  | COUNT(*) |
+---------+-------------+----------+
| Katze   | w           |        1 |
| Katze   | m           |        1 |
| Hund    | w           |        1 |
| Hund    | m           |        2 |
+---------+-------------+----------+
@end example

Oder wenn Sie die Anzahl von Tieren pro Geschlecht wissen wollen,
beschränkt auf die Tiere, deren Geschlecht bekannt ist:

@example
mysql> SELECT art, geschlecht, COUNT(*) FROM pet
    -> WHERE geschlecht IS NOT NULL
    -> GROUP BY art, geschlecht;
+---------+-------------+----------+
| art     | geschlecht  | COUNT(*) |
+---------+-------------+----------+
| Vogel   | w           |        1 |
| Katze   | w           |        1 |
| Katze   | m           |        1 |
| Hund    | w           |        1 |
| Hund    | m           |        2 |
| Hamster | w           |        1 |
| Schlange| m           |        1 |
+---------+-------------+----------+
@end example


@node Multiple tables,  , Counting rows, Retrieving data
@c German node Mehrere Tabellen
@subsubsection Mehr als eine Tabelle benutzen

@cindex Tabellen, mehrere

In der @code{pet}-Tabelle behalten Sie die Übersicht über Ihre Haustiere.
Wenn Sie weitere Informationen über sie aufzeichnen wollen, beispielsweise
Ereignisse in ihrem Leben wie Besuche beim Tierarzt oder wenn Nachwuchs zur
Welt kommt, brauchen Sie eine weitere Tabelle. Wie sollte diese aussehen?
Sie benötigt:

@itemize @bullet
@item
Den Namen des Haustiers, damit Sie wissen, auf welches Tier sich jedes
Ereignis bezieht.

@item
Ein Datum, damit Sie wissen, wann sich das Ereignis zugetragen hat.

@item
Ein Feld, um das Ereignis zu beschreiben.

@item
Ein Feld für den Typ des Ereignisses, wenn Sie in der Lage sein wollen,
Ereignisse zu kategorisieren.
@end itemize

Nach diesen Vorüberlegungen könnte das @code{CREATE TABLE}-Statement für
die @code{ereignis}-Tabelle wie folgt aussehen:

@example
mysql> CREATE TABLE ereignis (name VARCHAR(20), datum DATE,
    -> typ VARCHAR(15), bemerkung VARCHAR(255));
@end example

Wie bei der @code{pet}-Tabelle ist es am einfachsten, die anfänglichen
Datensätze mit Hilfe einer TAB-getrennten Textdatei einzuladen, die
folgende Informationen enthält:

@multitable @columnfractions .15 .15 .15 .55
@item Fluffy @tab 1995-05-15 @tab Nachwuchs @tab 4 Kätzchen, 3 weiblich, 1 männlich
@item Buffy @tab 1993-06-23 @tab Nachwuchs @tab 5 Hündchen, 2 weiblich, 3 männlich
@item Buffy @tab 1994-06-19 @tab Nachwuchs @tab 3 Hündchen, 3 weiblich
@item Chirpy @tab 1999-03-21 @tab Tierarzt @tab Schnabel gerade gebogen
@item Slim @tab 1997-08-03 @tab Tierarzt @tab Gebrochene Rippe
@item Bowser @tab 1991-10-12 @tab Zwinger
@item Fang @tab 1991-10-12 @tab Zwinger
@item Fang @tab 1998-08-28 @tab Geburtstag @tab Geschenk: neues Kauspielzeug
@item Claws @tab 1998-03-17 @tab Geburtstag @tab Geschenk: neues Flohhalsband
@item Whistler @tab 1998-12-09 @tab Geburtstag @tab Erster Geburtstag
@end multitable

Laden Sie die Datensätze wie folgt ein:

@example
mysql> LOAD DATA LOCAL INFILE "ereignis.txt" INTO TABLE ereignis;
@end example

Auf der Grundlage dessen, was Sie durch die Abfragen der @code{pet}-Tabelle
gelernt haben, sollten sie in der Lage sein, Abfragen der Datensätze der
@code{ereignis}-Tabelle durchzuführen, was prinzipiell dasselbe ist. Aber
wann ist die @code{ereignis}-Tabelle allein nicht ausreichend, um Fragen zu
beantworten, die Sie stellen könnten?

Nehmen wir an, Sie wollen herausfinden, wie alt jedes Haustier war, als es
Nachwuchs bekam. In der @code{ereignis}-Tabelle steht, wann das geschah,
aber um das Alter der Mutter auszurechnen, wird ihr Geburtstag benötigt.
Weil dieser in der @code{pet}-Tabelle steht, brauchen Sie für diese Anfrage
beide Tabellen:

@example
mysql> SELECT pet.name, (TO_DAYS(datum) - TO_DAYS(geburtstag))/365 AS age,anmerkung
    -> FROM pet, ereignis
    -> WHERE pet.name = ereignis.name AND typ = "Nachwuchs";
+--------+------+------------------------------------+
| name   | age  | anmerkung                          |
+--------+------+------------------------------------+
| Fluffy | 2.27 | 4 kätzchen, 3 weiblich, 1 männlich |
| Buffy  | 4.12 | 5 hündchen, 2 weiblich, 3 männlich |
| Buffy  | 5.10 | 3 hündchen, 3 weiblich             |
+--------+------+------------------------------------+
@end example

Zu dieser Anfrage gibt es einiges anzumerken:

@itemize @bullet
@item
In der @code{FROM}-Klausel stehen zwei Tabellen, weil die Anfrage aus
beiden Tabellen Informationen herausziehen muss.

@item
Wenn Sie Informationen aus mehreren Tabellen verbinden (englisch: join),
müssen Sie angeben, wie Datensätze in der einen Tabelle mit solchen in der
anderen Tabelle in Übereinstimmung gebracht werden können. Das ist einfach,
weil beide eine @code{name}-Spalte haben. Die Anfrage benutzt die
@code{WHERE}-Klausel, um Datensätze beider Tabellen basierend auf den
@code{name}-Werten in Übereinstimmung zu bringen.

@item
Weil die @code{name}-Spalte in beiden Tabellen vorkommt, müssen Sie
angeben, welche Tabelle Sie meinen, wenn Sie auf die Spalte verweisen. Das
wird gemacht, indem dem Spaltennamen der Tabellenname voran gestellt wird.
@end itemize

Sie müssen nicht unbedingt zwei verschiedene Tabellen haben, um eine
Verknüpfung (Join) durchzuführen. Manchmal ist es nützlich, eine Tabelle
mit sich selbst zu verknüpfen, wenn Sie nämlich Datensätze in einer Tabelle
mit Datensätze in derselben Tabelle vergleichen wollen. Um zum Beispiel
Zuchtpaare unter Ihren Haustieren zu finden, können Sie die
@code{pet}-Tabelle mit sich selbst verknüpfen, um Paare von männlichen und
weiblichen Tieren derselben Art zusammen zu bringen:

@example
mysql> SELECT p1.name, p1.geschlecht, p2.name, p2.geschlecht, p1.art
    -> FROM pet AS p1, pet AS p2
    -> WHERE p1.art = p2.art AND p1.geschlecht = "w" AND p2.geschlecht = "m";
+--------+-------------+--------+-------------+---------+
| name   | geschlecht  | name   | geschlecht  | art     |
+--------+-------------+--------+-------------+---------+
| Fluffy | w           | Claws  | m           | Katze   |
| Buffy  | w           | Fang   | m           | Hund    |
| Buffy  | w           | Bowser | m           | Hund    |
+--------+-------------+--------+-------------+---------+
@end example

In dieser Anfrage legen wir Aliase für den Tabellennamen fest, um auf die
Spalten verweisen zu können und um auseinander zu halten, auf welche
Instanz der Tabelle sich jede Spaltenreferenz bezieht.


@node Getting information, Examples, Database use, Tutorial
@c German node Informationen bekommen
@section Informationen über Datenbanken und Tabellen

@cindex Datenbanken, Informationen über
@cindex Tabellen, Informationen über
@findex DESCRIBE

Was ist, wenn Sie den Namen einer Datenbank oder Tabelle vergessen haben
oder für eine gegebene Tabelle die Struktur nicht mehr kennen (wie zum
Beispiel die Spalten heißen)? MySQL löst solcherlei Probleme mit diversen
Statements, die Informationen über die Datenbanken und Tabellen
bereitstellen, die es unterstützt.

@code{SHOW DATABASES} kennen Sie schon. Dieses listet die Datenbanken auf,
die vom Server verwaltet werden. Um herauszufinden, welche Datenbank
aktuell ausgewählt ist, benutzen Sie die @code{DATABASE()}-Funktion:

@example
mysql> SELECT DATABASE();
+------------+
| DATABASE() |
+------------+
| menagerie  |
+------------+
@end example

Wenn Sie noch keine Datenbank ausgewählt haben, ist das Ergebnis leer.

Um herauszufinden, welche Tabellen die aktuelle Datenbank enthält (wenn Sie
sich zum Beispiel über den Namen einer Tabelle nicht sicher sind), benutzen
Sie folgenden Befehl:

@example
mysql> SHOW TABLES;
+---------------------+
| Tables in menagerie |
+---------------------+
| ereignis            |
| pet                 |
+---------------------+
@end example

Wenn Sie die Struktur einer Tabelle sehen wollen, ist der
@code{DESCRIBE}-Befehl nützlich. Er zeigt Informationen über jede
Tabellenspalte an:

@example
mysql> DESCRIBE pet;
+------------+-------------+------+-----+---------+-------+
| Field      | Type        | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+-------+
| name       | varchar(20) | YES  |     | NULL    |       |
| besitzer   | varchar(20) | YES  |     | NULL    |       |
| art        | varchar(20) | YES  |     | NULL    |       |
| geschlecht | char(1)     | YES  |     | NULL    |       |
| geburtstag | date        | YES  |     | NULL    |       |
| sterbetag  | date        | YES  |     | NULL    |       |
+------------+-------------+------+-----+---------+-------+
@end example

@code{Field} zeigt den Spaltennamen, @code{Type} ist der Datentyp der
Spalte, @code{Null} zeigt an, ob die Spalte @code{NULL}-Werte enthalten darf
oder nicht, @code{Key} zeigt an, ob die Spalte indiziert ist oder nicht und
@code{Default} legt den Vorgabewert der Spalte fest.

Wenn Sie Indexe auf eine Tabelle haben, zeigt Ihnen @code{SHOW INDEX FROM
tabelle} Informationen über diese an.


@node Examples, Batch mode, Getting information, Tutorial
@c German node Beispiele
@section Beispiele gebräuchlicher Anfragen (Queries)

@cindex Anfragen, Beispiele
@cindex Beispiele, Anfragen

Hier finden sich Beispiele, wie geläufige Probleme mit MySQL gelöst werden
können.

Einige der Beispiele benutzen die Tabelle @code{shop}, die den Stückpreis
für jeden Artikel für bestimmte Händler enthält. Unter der Annahme, dass
jeder Händler einen einzelnen fest Preis pro Artikel hat, ist
(@code{artikel}, @code{haendler}) der Primärschlüssel für diese Datensätze.

Starten Sie das Kommandozeilen-Werkzeug @code{mysql} und wählen Sie eine
Datenbank aus:

@example
mysql ihr-datenbank-name
@end example

(Bei den meisten MySQL-Installationen können Sie die Datenbank 'test'
auswählen.)

Erzeugen Sie die Beispiel-Tabelle wie folgt:

@example
CREATE TABLE shop (
 artikel  INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
 haendler CHAR(20)                 DEFAULT ''     NOT NULL,
 preis    DOUBLE(16,2)             DEFAULT '0.00' NOT NULL,
 PRIMARY KEY(artikel, dealer));

INSERT INTO shop VALUES
(1,'A',3.45),(1,'B',3.99),(2,'A',10.99),(3,'B',1.45),(3,'C',1.69),
(3,'D',1.25),(4,'D',19.95);
@end example

Die Beispieldaten sehen jetzt so aus:

@example
mysql> SELECT * FROM shop;

+---------+---------+-------+
| artikel | haendler| preis |
+---------+---------+-------+
|    0001 | A       |  3.45 |
|    0001 | B       |  3.99 |
|    0002 | A       | 10.99 |
|    0003 | B       |  1.45 |
|    0003 | C       |  1.69 |
|    0003 | D       |  1.25 |
|    0004 | D       | 19.95 |
+---------+---------+-------+
@end example



@menu
* example-Maximum-column::      
* example-Maximum-row::         
* example-Maximum-column-group::  
* example-Maximum-column-group-row::  
* example-user-variables::      
* example-Foreign keys::        
* Searching on two keys::       
* Calculating days::            
@end menu

@node example-Maximum-column, example-Maximum-row, Examples, Examples
@c German node Beispiel Maximum-Spalte
@subsection Der höchste Wert einer Spalte

``Was ist die höchste Artikelnummer?''

@example
SELECT MAX(artikel) AS artikel FROM shop

+---------+
| artikel |
+---------+
|       4 |
+---------+
@end example


@node example-Maximum-row, example-Maximum-column-group, example-Maximum-column, Examples
@c German node Beispiel Maximum-Zeile
@subsection Die Zeile, die den höchsten Wert einer bestimmten Spalte enthält

``Suche Artikelnummer, Händler und Preis des teuersten Artikels.''

In ANSI-SQL wird das mit einer Unterabfrage (Sub-Query) durchgeführt:

@example
SELECT artikel, haendler, preis
FROM   shop
WHERE  preis=(SELECT MAX(preis) FROM shop)
@end example

In MySQL (was noch keine Unterabfragen hat) führen Sie das in zwei
Schritten durch:

@enumerate
@item
Mit einem @code{SELECT}-Statement ermitteln Sie den höchsten Preis in der
Tabelle.
@item
Mit diesem Wert stellen Sie die aktuelle Anfrage zusammen:
@example
SELECT artikel, haendler, preis
FROM   shop
WHERE  preis=19.95
@end example
@end enumerate

Eine andere Lösung besteht darin, alle Zeilen absteigend nach Preis zu
sortieren und nur die erste Zeile zu nehmen, indem Sie die
MySQL-spezifische @code{LIMIT}-Klausel benutzen:

@example
SELECT artikel, haendler, preis
FROM   shop
ORDER BY preis DESC
LIMIT 1
@end example

@strong{ACHTUNG}: Wenn es mehrere teuerste Artikel gibt (die zum Beispiel
alle 19.95 kosten), zeigt die @code{LIMIT}-Lösung nur einen davon!


@node example-Maximum-column-group, example-Maximum-column-group-row, example-Maximum-row, Examples
@c German node Beispiel Maximum-Spalte-Gruppe
@subsection Höchster Wert einer Spalte pro Gruppe

``Was ist der höchste Preis pro Artikel?''

@example
SELECT artikel, MAX(preis) AS preis
FROM   shop
GROUP BY artikel

+---------+-------+
| artikel | preis |
+---------+-------+
|    0001 |  3.99 |
|    0002 | 10.99 |
|    0003 |  1.69 |
|    0004 | 19.95 |
+---------+-------+
@end example


@node example-Maximum-column-group-row, example-user-variables, example-Maximum-column-group, Examples
@c German node Beispiel Maximum-Spalte-Gruppe-Zeile
@subsection Die Zeilen, die das gruppenweise Maximum eines bestimmten Felds enthalten

``Suche für jeden Artikel den oder die Händler mit den teuersten Preisen.''

In ANSI-SQL würden Sie das wie folgt mit einer Unterabfrage erledigen:

@example
SELECT artikel, haendler, preis
FROM   shop s1
WHERE  preis=(SELECT MAX(s2.preis)
              FROM shop s2
              WHERE s1.artikel = s2.artikel);
@end example

In MySQL macht man das am besten in mehreren Schritten:

@enumerate
@item
Die Liste (artikel,maxpreis) holen.
@item
Für jeden Artikel die korrespondierenden Zeilen holen, die den höchsten
Preis gespeichert haben.
@end enumerate

Das kann auf einfache Weise mit einer temporären Tabelle geschehen:

@example
CREATE TEMPORARY TABLE tmp (
        artikel INT(4) UNSIGNED ZEROFILL DEFAULT '0000' NOT NULL,
        preis   DOUBLE(16,2)             DEFAULT '0.00' NOT NULL);

LOCK TABLES shop read;

INSERT INTO tmp SELECT artikel, MAX(preis) FROM shop GROUP BY artikel;

SELECT shop.artikel, haendler, shop.preis FROM shop, tmp
WHERE shop.artikel=tmp.artikel AND shop.preis=tmp.preis;

UNLOCK TABLES;

DROP TABLE tmp;
@end example

Wenn Sie keine @code{TEMPORARY}-Tabelle benutzen, müssen Sie zusätzlich die
'tmp'-Tabelle sperren.

``Kann das mit einer einzigen Anfrage durchgeführt werden?''

Ja, aber nur unter Verwendung eines recht ineffizienten Tricks, den wir den
``MAX-CONCAT-Trick'' nennen:

@example
SELECT artikel,
       SUBSTRING( MAX( CONCAT(LPAD(preis,6,'0'),haendler) ), 7) AS haendler,
  0.00+LEFT(      MAX( CONCAT(LPAD(preis,6,'0'),haendler) ), 6) AS preis
FROM   shop
GROUP BY artikel;

+---------+---------+-------+
| artikel | haendler| preis |
+---------+---------+-------+
|    0001 | B       |  3.99 |
|    0002 | A       | 10.99 |
|    0003 | C       |  1.69 |
|    0004 | D       | 19.95 |
+---------+---------+-------+
@end example

Das letzte Beispiel kann etwas effizienter gemacht werden, wenn man das
Aufteilen der verketteten Spalte im Client durchführt.


@node example-user-variables, example-Foreign keys, example-Maximum-column-group-row, Examples
@c German node Beispiel Benutzer-Variablen
@subsection Wie Benutzer-Variablen verwendet werden

Sie können MySQL-Benutzer-Variablen verwenden, um Ergebnisse
zwischenzuspeichern, ohne sie in temporäre Variablen im Client speichern zu
müssen.
@xref{Variables}.

Um zum Beispiel die Artikel mit dem höchsten und dem niedrigsten Preis
herauszufinden, können Sie folgendes machen:

@example
select @@min_preis:=min(preis),@@max_preis:=max(preis) from shop;
select * from shop where preis=@@min_preis or preis=@@max_preis;

+---------+---------+-------+
| artikel | haendler| preis |
+---------+---------+-------+
|    0003 | D       |  1.25 |
|    0004 | D       | 19.95 |
+---------+---------+-------+
@end example


@node example-Foreign keys, Searching on two keys, example-user-variables, Examples
@c German node Beispiel Fremdschlüssel
@subsection Wie Fremdschlüssel (Foreign Keys) verwendet werden

@cindex Fremdschlüssel
@cindex Schlüssel, Fremdschlüssel

Sie brauchen keine Fremdschlüssel, um zwei Tabellen zu verknüpfen.

Das einzige, was MySQL nicht durchführt, ist der @code{CHECK}, um
sicherzustellen, dass die Schlüssel, die Sie benutzen, in der oder den
Tabelle(n) existieren, auf die Sie verweisen, und es löscht auch nicht
automatisch Zeilen aus einer Tabelle mit einer Fremdschlüssel-Definition.
Wenn Sie Ihre Schlüssel wie gewöhnlich benutzen, funktioniert das gut:


@example
CREATE TABLE personen (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    name CHAR(60) NOT NULL,
    PRIMARY KEY (id)
);

CREATE TABLE hemden (
    id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
    stil ENUM('t-shirt', 'polo', 'dress') NOT NULL,
    farbe ENUM('rot', 'blau', 'orange', 'weiß', 'schwarz') NOT NULL,
    besitzer SMALLINT UNSIGNED NOT NULL references personen,
    PRIMARY KEY (id)
);


INSERT INTO personen VALUES (NULL, 'Antonio Paz');

INSERT INTO hemden VALUES
(NULL, 'polo', 'blau', LAST_INSERT_ID()),
(NULL, 'dress', 'weiß', LAST_INSERT_ID()),
(NULL, 't-shirt', 'blau', LAST_INSERT_ID());


INSERT INTO personen VALUES (NULL, 'Lilliana Angelovska');

INSERT INTO hemden VALUES
(NULL, 'dress', 'orange', LAST_INSERT_ID()),
(NULL, 'polo', 'rot', LAST_INSERT_ID()),
(NULL, 'dress', 'blau', LAST_INSERT_ID()),
(NULL, 't-shirt', 'weiß', LAST_INSERT_ID());


SELECT * FROM personen;
+----+---------------------+
| id | name                |
+----+---------------------+
|  1 | Antonio Paz         |
|  2 | Lilliana Angelovska |
+----+---------------------+

SELECT * FROM hemden;
+----+---------+--------+----------+
| id | stil    | farbe  | besitzer |
+----+---------+--------+----------+
|  1 | polo    | blau   |     1    |
|  2 | dress   | weiß  |     1    |
|  3 | t-shirt | blau   |     1    |
|  4 | dress   | orange |     2    |
|  5 | polo    | rot    |     2    |
|  6 | dress   | blau   |     2    |
|  7 | t-shirt | weiß  |     2    |
+----+---------+--------+----------+


SELECT h.* FROM personen p, hemden h
 WHERE p.name LIKE 'Lilliana%'
   AND h.besitzer = p.id
   AND h.farbe <> 'weiß';

+----+-------+--------+----------+
| id | stil  | farbe  | besitzer |
+----+-------+--------+----------+
|  4 | dress | orange |     2    |
|  5 | polo  | rot    |     2    |
|  6 | dress | blau   |     2    |
+----+-------+--------+----------+
@end example


@node Searching on two keys, Calculating days, example-Foreign keys, Examples
@c German node Suche über zwei Schlüssel
@subsection Über zwei Schlüssel suchen

@findex UNION
@cindex Suchen, zwei Schlüssel
@cindex Schlüssel, suchen über zwei
MySQL optimiert derzeit noch nicht, wenn Sie über zwei unterschiedliche
Schlüssel suchen, die mit @code{OR} kombiniert werden (eine Suche mit einem
Schlüssel mit verschiedenen @code{OR}-Teilen wird recht gut optimiert):

@example
SELECT feld1_index, feld2_index FROM test_tabelle WHERE feld1_index = '1'
OR feld2_index = '1'
@end example

Der Grund liegt darin, dass wir bislang noch keine Zeit hatten, hierfür
eine effiziente Möglichkeit zu implementieren, die das für allgemeine Fälle
abhandelt. (Die @code{AND}-Handhabung ist im Vergleich jetzt komplett
allgemein und funktioniert sehr gut.)

In der Zwischenzeit können Sie dieses Problem sehr effizient lösen, indem
Sie eine @code{TEMPORARY}-Tabelle verwenden. Diese Art der Optimierung ist
ebenfalls sehr gut, wenn Sie sehr komplizierte Anfragen verwenden, bei
denen der SQL-Server die Optimierungen in falscher Reihenfolge durchführt.

@example
CREATE TEMPORARY TABLE tmp
SELECT feld1_index, feld2_index FROM test_tabelle WHERE feld1_index = '1';
INSERT INTO tmp
SELECT feld1_index, feld2_index FROM test_tabelle WHERE feld2_index = '1';
SELECT * from tmp;
DROP TABLE tmp;
@end example

Diese Möglichkeit der Anfrage ist im Endeffekt ein @code{UNION} von zwei
Anfragen.


@node Calculating days,  , Searching on two keys, Examples
@c German node Tage berechnen
@subsection Besuche pro Tag berechnen

@findex BIT_OR
@findex BIT_COUNT
@findex <<
@cindex Bit_Funktionen, Beispiel

Folgendes zeigt, wie Sie die Bit-Gruppen-Funktionen benutzen können, um die
Anzahl der Tage pro Monat zu zählen, in denen ein Benutzer eine Web-Seite
besucht hat.

@example
CREATE TABLE t1 (jahr YEAR(4), monat INT(2) UNSIGNED ZEROFILL, tag INT(2) UNSIGNED ZEROFILL);                                                            
INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),(2000,2,23),(2000,2,23);

SELECT jahr,monat,BIT_COUNT(BIT_OR(1<<tag)) AS tage FROM t1 GROUP BY jahr,monat;

Das gibt folgendes Ergebnis zurück:

+------+-------+------+
| jahr | monat | tage |
+------+-------+------+
| 2000 |    01 |    3 |
| 2000 |    02 |    2 |
+------+-------+------+
@end example

Dies berechnet, wie viele verschiedene Tage für eine gegebene
Jahr-Monats-Kombination benutzt wurden, bei automatischer Entfernung
doppelter Einträge (Duplikate).


@node Batch mode, Twin, Examples, Tutorial
@c German node Stapelbetrieb
@section @code{mysql} im Stapelbetrieb (Batch Mode)

@cindex Modi, Stapel
@cindex Stapelbetrieb
@cindex Laufenlassen, Stapelbetrieb
@cindex Skript-Dateien
@cindex Dateien, Skript

In den vorherigen Abschnitten haben Sie @code{mysql} interaktiv benutzt, um
Anfragen einzugeben und die Ergebnisse zu betrachten. Sie können
@code{mysql} auch im Stapelbetrieb benutzen. Dafür schreiben Sie dei
Befehle, die Sie ausführen wollen, in eine Datei, und teilen @code{mysql}
dann mit, seine Eingaben aus dieser Datei zu lesen:

@example
shell> mysql < stapel-datei
@end example

Wenn Sie auf der Kommandozeile Verbindungsparameter angeben müssen, könnte
der Befehl wie folgt aussehen:

@example
shell> mysql -h host -u user -p < stapel-datei
Enter password: ********
@end example

Wenn Sie @code{mysql} auf diese Weise benutzen, erzeugen Sie eine
Skript-Datei und führen dann das Skript aus.

Warum sollten Sie ein Skript benutzen? Hier sind ein paar Gründe:

@itemize @bullet
@item
Wenn Sie eine Anfrage wiederholt ausführen (sagen wir jeden Tag oder jede
Woche), vermeiden Sie mit einem Skript, dass Sie sie jedes Mal zur
Ausführung erneut eintippen müssen.

@item
Sie können aus existierenden Anfragen neue Anfragen erzeugen, die ähnlich
sind, indem Sie die Skript-Dateien kopieren und editieren.

@item
Der Stapelbetrieb kann auch für die Entwicklung einer Anfrage nützlich
sein, insbesondere, wenn Sie mehrzeilige Befehle oder Befehlssequenzen aus
mehreren Statements entwickeln. Wenn Sie einen Fehler machen, müssen Sie
nicht alles noch einmal tippen, sondern editieren einfach Ihr Skript, um
den Fehler zu beheben, und weisen @code{mysql} an, es erneut auszuführen.

@item
Wenn Sie eine Anfrage haben, die eine größere Ausgabe erzeugt, können Sie
die Ausgabe durch einen Pager laufen lassen, statt zuzusehen, wie Sie über
den Bildschirm flimmert:

@example
shell> mysql < stapel-datei | more
@end example

@item
Für weitere Verarbeitung können Sie die Ausgabe auch in eine Datei lenken:

@example
shell> mysql < stapel-datei > mysql.ausgabe
@end example

@item
Sie können Ihr Skript an andere Leute verteilen, so dass auch sie die
Befehle laufen lassen können.

@item
In einigen Situationen ist interaktive Benutzung nicht angebracht, zum
Beispiel dann, wenn Sie eine Anfrage durch einen @code{cron}-Job ausführen
lassen. In diesem Fall brauchen Sie Stapelbetrieb.
@end itemize

Das Standard-Ausgabeformat ist anders (präziser), wenn Sie @code{mysql} im
Stapelbetrieb laufen lassen, als wenn Sie es interaktiv nutzen. Die Ausgabe
von @code{SELECT DISTINCT art FROM pet} zum Beispiel sieht so aus, wenn Sie
sie interaktiv laufen lassen:

@example
+---------+
| art     |
+---------+
| Vogel   |
| Katze   |
| Hund    |
| Hamster |
| Schlange|
+---------+
@end example

Aber wie folgt, wenn sie im Stapelbetrieb läuft:

@example
art
Vogel
Katze
Hund
Hamster
Schlange
@end example

Wenn Sie im Stapelbetrieb das interaktive Ausgabeformat haben wollen,
benutzen Sie @code{mysql -t}. Um die Befehle auszugeben, die ausgeführt
werden, benutzen Sie @code{mysql -vvv}.


@node Twin, Apache, Batch mode, Tutorial
@c German node Twin
@section Anfragen aus dem Zwillings-Projekt

@cindex Zwillingsforschung, Anfragen
@cindex Anfragen, Zwillingsforschungs-Projekt

Bei Analytikerna und Lentus haben wir die Systeme und die Feldarbeit für
ein großes Forschungsprojekt gemacht. Dieses Projekt ist eine
Zusammenarbeit zwischen dem Institut für Umweltmedizin des Karolinska
Institutes, Stockholm, und der Abteilung für klinische Forschung bei
Altersprozessen und Psychologie der University of Southern California.

Das Projekt beinhaltet einen Screening-Teil, bei dem alle Zwillinge in
Schweden, die älter als 65 Jahre sind, per Telefon interviewt wurden.
Zwillinge, die bestimmte Kriterien erfüllen, werden im nächsten Schritt
weiter untersucht. In diesem späteren Stadium werden Zwillinge, die
teilnehmen wollen, von einem Arzt-Schwester-Team besucht. Einige
Untersuchungen beinhalten physische und neuropsychologische Untersuchungen,
Labortests, Neuroimaging, Bewertungen des psychischen Zustands und eine
Sammlung der Familiengeschichten. Zusätzlich werden Daten über medizinische
und umweltbedingte Risikofaktoren gesammelt.

Weitere Informationen zu den Zwillingsstudien finden Sie hier:

@example
@url{http://www.imm.ki.se/TWIN/TWINGREATBRITAINW.HTM}
@end example

Der spätere Teil des Projekts wird mit einer Web-Schnittstelle verwaltet,
die Perl und MySQL benutzt.

Jeden Abend werden alle Daten der Interviews in eine MySQL-Datenbank
verschoben.



@menu
* Twin pool::                   
* Twin event::                  
@end menu

@node Twin pool, Twin event, Twin, Twin
@c German node Twin-Pool
@subsection Alle nicht verteilten Zwillinge finden

Mit folgender Anfrage wird festgelegt, wer in den zweiten Teil des Projekts
geht:

@example
select
        concat(p1.id, p1.tvab) + 0 as tvid,
        concat(p1.christian_name, " ", p1.surname) as Name,
        p1.postal_code as Code,
        p1.city as City,
        pg.abrev as Area,
        if(td.participation = "Aborted", "A", " ") as A,
        p1.dead as dead1,
        l.event as event1,
        td.suspect as tsuspect1,
        id.suspect as isuspect1,
        td.severe as tsevere1,
        id.severe as isevere1,
        p2.dead as dead2,
        l2.event as event2,
        h2.nurse as nurse2,
        h2.doctor as doctor2,
        td2.suspect as tsuspect2,
        id2.suspect as isuspect2,
        td2.severe as tsevere2,
        id2.severe as isevere2,
        l.finish_date
from
        twin_project as tp
        /* For Twin 1 */
        left join twin_data as td on tp.id = td.id and tp.tvab = td.tvab
        left join informant_data as id on tp.id = id.id and tp.tvab = id.tvab
        left join harmony as h on tp.id = h.id and tp.tvab = h.tvab
        left join lentus as l on tp.id = l.id and tp.tvab = l.tvab
        /* For Twin 2 */
        left join twin_data as td2 on p2.id = td2.id and p2.tvab = td2.tvab
        left join informant_data as id2 on p2.id = id2.id and p2.tvab = id2.tvab
        left join harmony as h2 on p2.id = h2.id and p2.tvab = h2.tvab
        left join lentus as l2 on p2.id = l2.id and p2.tvab = l2.tvab,
        person_data as p1,
        person_data as p2,
        postal_groups as pg
where
        /* p1 gets main twin and p2 gets his/her twin. */
        /* ptvab is a field inverted by tvab */
        p1.id = tp.id and p1.tvab = tp.tvab and
        p2.id = p1.id and p2.ptvab = p1.tvab and
        /* Just the sceening survey */
        tp.survey_no = 5 and
        /* Skip if partner died before 65 but allow emigration (dead=9) */
        (p2.dead = 0 or p2.dead = 9 or
         (p2.dead = 1 and
          (p2.sterbetag_date = 0 or
           (((to_days(p2.sterbetag_date) - to_days(p2.geburtstagday)) / 365)
            >= 65))))
        and
        (
        /* Twin is suspect */
        (td.future_contact = 'Yes' and td.suspect = 2) or
        /* Twin is suspect - Informant is Blessed */
        (td.future_contact = 'Yes' and td.suspect = 1 and id.suspect = 1) or
        /* No twin - Informant is Blessed */
        (ISNULL(td.suspect) and id.suspect = 1 and id.future_contact = 'Yes') or
        /* Twin broken off - Informant is Blessed */
        (td.participation = 'Aborted'
         and id.suspect = 1 and id.future_contact = 'Yes') or
        /* Twin broken off - No inform - Have partner */
        (td.participation = 'Aborted' and ISNULL(id.suspect) and p2.dead = 0))
        and
        l.event = 'Finished'
        /* Get at area code */
        and substring(p1.postal_code, 1, 2) = pg.code
        /* Not already distributed */
        and (h.nurse is NULL or h.nurse=00 or h.doctor=00)
        /* Has not refused or been aborted */
        and not (h.status = 'Refused' or h.status = 'Aborted'
        or h.status = 'Died' or h.status = 'Other')
order by
        tvid;
@end example

Einige Erläuterungen:
@table @asis
@item @code{concat(p1.id, p1.tvab) + 0 as tvid}
Wir wollen nach den verketteten @code{id} und @code{tvab} in numerischer
Reihenfolge sortieren. Indem wir @code{0} hinzufügen, bringen wir MySQL
dazu, das Ergebnis als Zahl zu behandeln.
@item Spalte @code{id}
Diese identifiziert ein Zwillingspaar. Sie ist in allen Tabellen Schlüssel.
@item Spalte @code{tvab}
Diese identifiziert ein Zwillingspaar. Sie hat einen Wert von @code{1} oder
@code{2}.
@item Spalte @code{ptvab}
Sie ist die Umkehrung von @code{tvab}. Wenn @code{tvab} @code{1} ist, ist
sie @code{2}, und umgekehrt. Sie ist dafür da, MySQL die Optimierung der
Anfrage zu erleichtern.
@end table
Diese Anfrage demonstriert unter anderem, wie man ein Nachschlagen (Lookup)
in einer Tabelle von derselben Tabelle aus mit einem Join durchführt
(@code{p1} und @code{p2}). In dem Beispiel wird das dazu benutzt, um
festzustellen, ob der Partner eines Zwillings vor Erreichen des 65.
Lebensjahrs starb. Wenn das der Fall ist, wird die Zeile nicht
zurückgegeben.

Das Geschilderte existiert in allen Tabellen mit zwillingsbezogenen
Informationen. Wir haben einen Schlüssel auf beide @code{id,tvab} (alle
Tabellen), und auf @code{id,ptvab} (@code{person_data}), um Anfragen
schneller zu machen.

Auf unserer Produktionsmaschine (einer 200MHz-UltraSPARC) gibt diese
Anfrage etwa 150 bis 200 Zeilen zurück und benötigt weniger als eine
Sekunde.

Die aktuelle Anzahl von Datensätzen in den oben benutzten Tabellen:
@multitable @columnfractions .3 .5
@item @strong{Tabelle}          @tab @strong{Zeilen}
@item @code{person_data}        @tab 71074
@item @code{lentus}		@tab 5291
@item @code{twin_project}       @tab 5286
@item @code{twin_data}		@tab 2012
@item @code{informant_data}	@tab 663
@item @code{harmony}		@tab 381
@item @code{postal_groups}	@tab 100
@end multitable


@node Twin event,  , Twin pool, Twin
@c German node Twin-Ereignis
@subsection Eine Tabelle über den Zustand von Zwillingspaaren zeigen

Jedes Interview endet mit einem Statuscode, genannt @code{ereignis}. Die
unten stehende Anfrage wird benutzt, um eine Tabelle über alle
Zwillingspaare anzuzeigen, kombiniert mit dem Ereignis. Das zeigt an, wie
viele Paare beider Zwillingen im Zustand beendet sind, bei wie vielen
Paaren ein Zwilling im Zustand beendet ist, welche ein Interview abgelehnt
haben usw.

@example
select
        t1.event,
        t2.event,
        count(*)
from
        lentus as t1,
        lentus as t2,
        twin_project as tp
where
        /* We are looking at one pair at a time */
        t1.id = tp.id
        and t1.tvab=tp.tvab
        and t1.id = t2.id
        /* Just the sceening survey */
        and tp.survey_no = 5
        /* This makes each pair only appear once */
        and t1.tvab='1' and t2.tvab='2'
group by
        t1.event, t2.event;
@end example


@node Apache,  , Twin, Tutorial
@c German node Apache
@section MySQL mit Apache benutzen

@cindex Apache




Der Contrib-Abschnitt beinhaltet Programme, mit denen Sie Ihre Benutzer
durch eine MySQL-Datenbank authentifizieren können, und mit denen Sie Ihre
Logdateien in eine MySQL-Tabelle schreiben können. @xref{Contrib}.

Sie können das Log-Format von Apache so ändern, dass es durch MySQL leicht
gelesen werden kann, indem Sie folgendes in die Apache-Konfigurationsdatei
schreiben:

@example
LogFormat \
        "\"%h\",%@{%Y%m%d%H%M%S@}t,%>s,\"%b\",\"%@{Content-Type@}o\",  \
        \"%U\",\"%@{Referer@}i\",\"%@{User-Agent@}i\""
@end example

In MySQL können Sie dann etwas wie das hier tun:

@example
LOAD DATA INFILE '/local/access_log' INTO TABLE tabelle
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\'
@end example


@node MySQL Database Administration, MySQL Optimisation, Tutorial, Top
@c German node MySQL-Datenbankadministration
@chapter MySQL-Datenbankadministration



@menu
* Configuring MySQL::           
* Privilege system::            
* User Account Management::     
* Disaster Prevention::         
* Database Administration::     
* Localisation::                
* Server-Side Scripts::         
* Client-Side Scripts::         
* Log Files::                   
* Replication::                 
@end menu

@node Configuring MySQL, Privilege system, MySQL Database Administration, MySQL Database Administration
@c German node MySQL konfigurieren
@section MySQL konfigurieren




@menu
* Command-line options::        
* Option files::                
* Installing many servers::     
* Multiple servers::            
@end menu

@node Command-line options, Option files, Configuring MySQL, Configuring MySQL
@c German node Kommandozeilenoptionen
@subsection mysqld-Kommandozeilenoptionen

@findex Kommandozeilenoptionen
@cindex Optionen, Kommandozeile
@cindex mysqld-Optionen

@code{mysqld} akzeptiert folgende Kommandozeilenoptionen:

@table @code
@item --ansi
ANSI-SQL-Syntax anstelle von MySQL-Syntax benutzen. @xref{ANSI mode}.

@item -b, --basedir=path
Pfad zum Installationsverzeichnis. Gewöhnlich werden alle Pfade relativ zu
diesem aufgelöst.

@item --big-tables
große Ergebnismengen zulassen, indem alle temporären Mengen in eine Datei
gesichert werden. Das löst die meisten 'table full'-Fehler, verlangsamt
aber in den Fällen Anfragen, in denen Tabellen im Speicher ausreichen
würden. Ab Version 3.23.2 ist MySQL in der Lage, das automatisch zu lösen,
indem für kleine temporäre Tabellen der Arbeitsspeicher benutzt wird und
auf Festplatten-Tabellen umgeschaltet wird, wenn das nötig ist.

@item --bind-address=IP
IP-Adresse zum Anbinden (bind).

@item --character-sets-dir=path
Verzeichnis, wo Zeichensätze sind.  @xref{Character sets}.

@item --chroot=path
Chroot den @code{mysqld}-Daemon beim Start. Empfohlene
Sicherheitsmaßnahme. Wird allerdings @code{LOAD DATA INFILE} und
@code{SELECT ... INTO OUTFILE} etwas einschränken.

@item --core-file
Schreibt eine Core-Datei, wenn @code{mysqld} stirbt. Auf manchen Systemen
müssen Sie zusätzliche @code{--core-file-size} für @code{safe_mysqld}
angeben. @xref{safe_mysqld, ,@code{safe_mysqld}}.

@item -h, --datadir=path
Pfad zum Datenbank-Wurzelverzeichnis.

@item --default-character-set=charset
Setzt den vorgabemäßigen Zeichensatz.  @xref{Character sets}.

@item --default-table-type=type
Setzt den vorgabemäßigen Tabellentyp für Tabellen. @xref{Table types}.

@item --debug[...]=
Wenn MySQL mit @code{--with-debug} konfiguriert ist, können Sie diese
Option benutzen, um eine Trace-Datei darüber zu erhalten, was @code{mysqld}
tut. @xref{Making trace files}.

@item --delay-key-write-for-all-tables
Schlüsselpuffer (Key Buffer) für jegliche @code{MyISAM}-Tabellen nicht
leeren (flush).
@xref{Server parameters}.

@item --enable-locking
System-Sperren einschalten. Beachten Sie, dass Sie bei der Benutzung dieser
Option auf Systemen, die kein voll funktionsfähiges lockd() besitzen (wie
Linux), mysqld leicht zum Deadlock bringen können.

@item -T, --exit-info
Eine Bit-Maske verschiedener Flags, mit denen man den mysqld-Server
debuggen kann. Man sollte diese Option nicht benutzen, wenn man nicht ganz
genau weiß, was sie tut!

@item --flush
Alle Änderungen nach jedem SQL-Befehl auf Platte zurückschreiben (flush).
Normalerweise schreibt MySQL alle Änderungen nach jedem SQL-Befehl auf
Platte und läßt das Betriebssystem sich um das Synchronisieren auf Platte
kümmern.
@xref{Crashing}.

@item -?, --help
Kurze Hilfe ausgeben und beenden.

@item --init-file=file
Beim Start SQL-Befehle aus dieser Datei lesen.

@item -L, --language=...
Client-Fehlermeldungen in der angegebenen Sprache. Kann als voller Pfad
angegeben werden. @xref{Languages}.

@item -l, --log[=datei]
Loggt Verbindungen und Anfragen in datei. @xref{Query log}.

@item --log-isam[=datei]
Loggt alle ISAM- / MyISAM-Änderungen in datei (wird nur benutzt, um ISAM /
MyISAM zu debuggen).

@item --log-slow-queries[=datei]
Loggt alle Anfragen, die länger als @code{long_query_time} Sekunden für die
Ausführung benötigt haben, in datei. @xref{Slow query log}.

@item --log-update[=datei]
Loggt Updates in @code{datei.#}, wobei @code{#} eine eindeutige Zahl ist,
falls nicht vorgegeben.
@xref{Update log}.

@item --log-long-format
Loggt einige zusätzliche Informationen ins Update-Log. Wenn Sie
@code{--log-slow-queries} benutzen, werden Anfragen, die keine Indexe
benutzen, in die Langsame-Anfragen-Log-Datei geloggt.

@item --low-priority-updates
Operationen, die Tabellen ändern
(@code{INSERT}/@code{DELETE}/@code{UPDATE}), haben geringere Priorität als
Selects. Das kann auch mit @code{@{INSERT | REPLACE | UPDATE | DELETE@}
LOW_PRIORITY ...} durchgeführt werden, um lediglich die Priorität einer
einzelnen Anfrage zu verringern, oder mit @code{SET OPTION
SQL_LOW_PRIORITY_UPDATES=1}, um die Priorität in einem Thread zu ändern.
@xref{Table locking}.

@item --memlock
Sperrt den @code{mysqld}-Prozess in den Arbeitsspeicher. Das funktioniert
nur, wenn Ihr System den @code{mlockall()}-Systemaufruf versteht (wie
Solaris). Das kann helfen, wenn Sie Probleme damit haben, dass Ihr
Betriebssystem @code{mysqld} veranlasst, auf Platte zu swappen.

@item --myisam-recover [=option[,option...]]], wobei option eine
Kombination von @code{DEFAULT}, @code{BACKUP}, @code{FORCE} oder
@code{QUICK} ist. Sie können sie auch explizit auf @code{""} setzen, wenn
Sie diese Option ausschalten wollen. Wenn die Option benutzt wird,
überprüft @code{mysqld} beim Öffnen, ob die Tabelle als zerstört markiert
ist oder ob die Tabelle nicht ordnungsgemäß geschlossen wurde. (Die letzte
Option funktioniert nur, wenn Sie mysqld mit @code{--skip-locking} laufen
lassen). Wenn das der Fall ist, läßt @code{mysqld} eine Überprüfung der
Tabelle laufen. Wenn die Tabelle beschädigt war, versucht @code{mysqld},
sie zu reparieren.

Folgende Optionen beeinflussen, wie repair funktioniert.

@multitable @columnfractions .3 .7
@item DEFAULT  @tab Dasselbe, als würde man für @code{--myisam-recover}
                    keine Option angeben.
@item BACKUP   @tab Wenn die Tabelle während der Wiederherstellung geändert
                    wurde, eine Datensicherung der @file{tabelle.MYD}-Datendatei als
                    @file{tabelle-datetime.BAK} speichern.
@item FORCE    @tab Eine Wiederherstellung selbst dann laufen lassen, wenn
                    man mehr als eine Zeile aus der .MYD-Datei verlieren wird.
@item QUICK    @tab Die Zeilen der Tabelle nicht überprüfen, wenn es keine
                    gelöschten Blocks gibt.
@end multitable

Bevor eine Tabelle automatisch repariert wird, fügt MySQL darüber eine
Bemerkung in das Fehler-Log. Wenn Sie in der Lage sein wollen, die meisten
Sachen ohne Benutzer-Intervention zu beheben, sollten Sie die Optionen
@code{BACKUP,FORCE} benutzen. Das erzwingt ein Reparieren einer Tabelle,
selbst wenn dabei einige Zeilen gelöscht würden, erhält aber die alte
Datendatei als Datensicherung, so dass Sie später herausfinden können, was
passiert ist.

@item --pid-file=pfad
Pfad zur pid-Datei, die von @code{safe_mysqld} benutzt wird.

@item -P, --port=...
Port-Nummer, um auf TCP/IP-Verbindungen zu warten (listen).

@item -o, --old-protocol
Das 3.20-Protokoll für Kompatibilität mit einigen sehr alten Clients
benutzen.

@item --one-thread
Nur einen Thread benutzen (zum Debuggen unter Linux). @xref{Debugging server}.

@item -O, --set-variable var=option
Weist einer Variablen einen Wert zu. @code{--help} listet Variablen auf.
Sie finden eine komplette Beschreibung aller Variablen im @code{SHOW
VARIABLES}-Abschnitt dieses Handbuchs. @xref{SHOW VARIABLES}. Der Abschnitt
über das Tunen der Serverparameter enthält Informationen darüber, wie man
diese optimiert. @xref{Server parameters}.

@item --safe-mode
Einige Optimierungsschritte überspringen. Setzt
@code{--skip-delay-key-write} voraus.

@item --safe-show-database
Keine Datenbanken anzeigen, für die der Benutzer keine Zugriffsrechte hat.

@item --safe-user-create
Wenn das angeschaltet ist, kann ein Benutzer keine neuen Benutzer mit dem
GRANT-Befehl anlegen, wenn der Benutzer kein @code{INSERT}-Zugriffsrecht
auf die @code{mysql.user}-Tabelle oder irgend welche Spalten dieser Tabelle
hat.

@item --skip-concurrent-insert
Die Fähigkeit abschalten, gleichzeitig auf @code{MyISAM}-Tabellen
auszuwählen (select) und einzufügen (insert). (Sollte nur benutzt werden,
wenn Sie der Meinung sind, ein Bug in diesem Feature gefunden zu haben.)

@item --skip-delay-key-write
Die @code{delay_key_write}-Option für alle Tabellen ignorieren.
@xref{Server parameters}.

@item --skip-grant-tables
Diese Option veranlasst den Server, das Zugriffsrechte-System überhaupt
nicht zu benutzen. Das gibt jedem @emph{vollen Zugriff} auf alle
Datenbanken! (Einen laufenden Server können Sie anweisen, die
Berechtigungstabellen erneut zu verwenden, indem Sie @code{mysqladmin
flush-privileges} oder @code{mysqladmin reload} ausführen.)

@item --skip-host-cache
Nie den Host-Name-Cache für schnellere Name-IP-Auflösung benutzen, sondern
statt dessen bei jeder Verbindung beim DNS-Server anfragen. @xref{DNS}.

@item --skip-locking
System-Sperren nicht benutzen. Um @code{isamchk} oder @code{myisamchk}
auszuführen, müssen Sie den Server herunter fahren. @xref{Stability}.
Beachten Sie, dass Sie in MySQL-Version 3.23 @code{REPAIR} und @code{CHECK}
benutzen können, um @code{MyISAM}-Tabellen zu reparieren / zu prüfen.

@item --skip-name-resolve
Hostnamen werden nicht aufgelöst. Alle @code{Host}-Spaltenwerte in den
Berechtigungstabellen müssen IP-Nummern oder @code{localhost} sein.
@xref{DNS}.

@item --skip-networking
Auf überhaupt keine TCP/IP-Verbindungen warten (listen). Jede Interaktion
mit @code{mysqld} muss über Unix-Sockets erfolgen. Diese Option wird
ausdrücklich empfohlen für Systeme, auf denen nur lokale Anfragen
(Requests) erlaubt sind. @xref{DNS}.

@item --skip-new
Keine neuen, möglicherweise falschen Routinen benutzen. Setzt
@code{--skip-delay-key-write} voraus. Setzt ausserdem den vorgabemäßigen
Tabellentyp auf @code{ISAM}. @xref{ISAM}.

@item --skip-symlink
Keine Dateien löschen oder umbenennen, auf die eine mit Symlink verknüpfte
Datei im Daten-Verzeichnis zeigt.

@item --skip-safemalloc
Wenn MySQL mit @code{--with-debug=full} konfiguriert wird, überprüfen alle
Programme den Arbeitsspeicher auf Überlauf, bei jeder Speicher-Allokation
und -Freigabe. Da dieses Prüfen sehr langsam ist, können Sie es vermeiden,
wenn Sie keine Arbeitsspeicherprüfung benötigten, indem Sie diese Option
benutzen.

@item --skip-show-database
Keine 'SHOW DATABASE'-Befehle zulassen, wenn der Benutzer keine
@strong{process}-Berechtigung hat.

@item --skip-stack-trace
Keine Stack-Traces schreiben. Diese Option ist nützlich, wenn Sie
@code{mysqld} unter einem Debugger laufen lassen. @xref{Debugging server}.

@item --skip-thread-priority
Benutzung von Thread-Prioritäten abschalten, um schnellere Antwortzeiten zu
erzielen.

@item --socket=pfad
Socket-Datei, die anstelle des vorgabemäßigen @code{/tmp/mysql.sock} für
lokale Verbindungen benutzt wird.

@item --sql-mode=option[,option[,option...]]
Option kann jede beliebige Kombination von @code{REAL_AS_FLOAT},
@code{PIPES_AS_CONCAT}, @code{ANSI_QUOTES}, @code{IGNORE_SPACE},
@code{SERIALIZE} und @code{ONLY_FULL_GROUP_BY} sein. Sie kann auch leer
sein (@code{""}), wenn Sie dies zurücksetzen wollen.

Alle oben angegebenen Optionen festlegen ist dasselbe wie --ansi benutzen.
Mit dieser Option kann man nur benötigte SQL-Modi anschalten.
@xref{ANSI mode}.

@item transaction-isolation= @{ READ-UNCOMMITTED | READ-COMMITTED | REPEATABLE-READ | SERIALIZABLE @}
Setzt das vorgabemäßige Transaktions-Isolations-Level.
@c German FIX unsplit @xref
@xref{SET TRANSACTION}.

@item -t, --tmpdir=pfad
Pfad für temporäre Dateien. Es kann nützlich sein, wenn Ihr vorgabemäßiges
@code{/tmp}-Verzeichnis auf einer Partition liegt, die zu klein ist, um
temporäre Tabellen zu speichern.

@item -u, --user=benutzername
Den @code{mysqld}-Daemon unter dem Benutzer @code{benutzername} laufen
lassen. Diese Option ist @emph{zwingend notwendig}, wenn @code{mysqld} als
Root gestartet wird.

@item -V, --version
Versionsinformationen ausgeben und beenden.

@item -W, --warnings
Warnmeldungen wie @code{Aborted connection...} in die @code{.err}-Datei
ausgeben. @xref{Communication errors}.
@end table


@node Option files, Installing many servers, Command-line options, Configuring MySQL
@c German node Optionsdateien
@subsection my.cnf-Optionsdateien

@cindex Vorgabemäßige Optionen
@cindex Optionsdateien
@cindex Erzeugen, vorgabemäßige Startoptionen
@cindex Startoptionen, vorgabemäßige

Seit Version 3.22 kann MySQL vorgabemäßige Startoptionen für den Server
und für Clients aus Optionsdateien lesen.

MySQL liest Vorgabeoptionen aus folgenden Dateien unter Unix:

@tindex .my.cnf-Datei
@multitable @columnfractions .3 .7
@item @strong{Dateiname} @tab @strong{Zweck}
@item @code{/etc/my.cnf} @tab Globale Optionen
@item @code{DATADIR/my.cnf} @tab Server-spezifische Optionen
@item @code{defaults-extra-file} @tab Die Datei, die mit --defaults-extra-file=# festgelegt wird
@item @code{~/.my.cnf} @tab Benutzerspezifische Optionen
@end multitable

@code{DATADIR} ist das MySQL-Daten-Verzeichnis (typischerweise
@file{/usr/local/mysql/data} bei einer Binärinstallation oder
@file{/usr/local/var} bei einer Quellinstallation). Beachten Sie, dass das
das Verzeichnis ist, das zur Konfigurationszeit festgelegt wurde, nicht
das, das mit @code{--datadir} festgelegt wird, wenn @code{mysqld} startet!
(@code{--datadir} hat keinen Einfluss darauf, wo der Server nach
Optionsdateien sucht, denn er sucht nach ihnen, bevor er irgend welche
Kommandozeilenargumente verarbeitet.)

MySQL liest Vorgabeoptionen aus folgenden Dateien unter Windows:

@multitable @columnfractions .3 .7
@item @strong{Dateiname} @tab @strong{Zweck}
@item @code{Windows-System-Verzeichnis\my.ini} @tab Globale Optionen
@item @code{C:\my.cnf} @tab Globale Optionen
@item @code{C:\mysql\data\my.cnf} @tab Server-spezifische Optionen
@end multitable

Beachten Sie, dass Sie unter Windows alle Pfade mit @code{/} statt mit
@code{\} angeben sollten. Wenn Sie @code{\} benutzen, müssen Sie das
doppelt (@code{\\}) tun, weil @code{\} in MySQL das Fluchtzeichen
(Escape-Character) ist.

@cindex Umgebungsvariablen
MySQL versucht, Optionsdateien in der oben angegebenen Reihenfolge zu
lesen. Wenn es mehrere Optionsdateien gibt, erlangt eine Option, die in
einer Datei festgelegt wird, die später gelesen wird, Vorrang über dieselbe
Option, die in einer sonstigen Optionsdatei festgelegt wurde. Optionen, die
auf der Kommandozeile festgelegt werden, erlangen Vorrang vor Optionen in
jeglichen Optionsdateien. Einige Optionen können durch Umgebungsvariablen
festgelegt werden. Optionen, die auf der Kommandozeile oder in
Optionsdateien festgelegt werden, haben Vorrang vor Werten in
Umgebungsvariablen. @xref{Environment variables}.
Folgende Programme unterstützen Optionsdateien:  @code{mysql},
@code{mysqladmin}, @code{mysqld}, @code{mysqldump}, @code{mysqlimport},
@code{mysql.server}, @code{myisamchk} und @code{myisampack}.

Sie können Optionsdateien benutzen, um jede beliebig lange Option
festzulegen, die ein Programm unterstützt! Starten Sie das Programm mit
@code{--help}, um eine Liste der verfügbaren Optionen zu erhalten.

Eine Optionsdatei kann Zeilen der folgenden Formate enthalten:

@table @code
@item #Kommentar
Kommentarzeilen fangen mit @samp{#} oder @samp{;} an. Leere Zeilen werden
ignoriert.

@item [group]
@code{group} ist der Name des Programms oder der Gruppe, für das oder die
Sie Optionen setzen wollen. Nach einer Gruppen-Zeile beziehen sich alle
@code{option}- oder @code{set-variable}-Zeilen auf die benannte Gruppe, bis
zum Ende der Optionsdatei oder bis eine andere Gruppe angegeben wird.

@item option
Das ist äquivalent zu @code{--option} auf der Kommandozeile.

@item option=value
Das ist äquivalent zu @code{--option=value} auf der Kommandozeile.

@item set-variable = variable=value
Das ist äquivalent zu @code{--set-variable variable=value} auf der Kommandozeile.
Diese Syntax muss verwendet werden, um eine @code{mysqld}-Variable zu
setzen.
@end table

Die @code{client}-Gruppe gestattet Ihnen, Optionen anzugeben, die sich auf
alle MySQL-Clients (nicht auf @code{mysqld}) beziehen. Diese Gruppe eignet
sich bestens dafür, das Passwort festzulegen, das Sie benutzen, um sich mit
dem Server zu verbinden. (Stellen Sie jedoch sicher, dass die Optionsdatei
nur für Sie les- und schreibbar ist.)

Beachten Sie, dass bei Optionen und Werten alle führenden Leerzeichen und
solche am Zeilenende automatisch entfernt werden. Sie können in der
Zeichenkette für den Wert die Escape-Sequenzen @samp{\b}, @samp{\t},
@samp{\n}, @samp{\r}, @samp{\\} und @samp{\s} benutzen (@samp{\s} ist das
Leerzeichen).

Hier ist eine typische globale Optionsdatei:

@example
[client]
port=3306
socket=/tmp/mysql.sock

[mysqld]
port=3306
socket=/tmp/mysql.sock
set-variable = key_buffer_size=16M
set-variable = max_allowed_packet=1M

[mysqldump]
quick
@end example

Hier ist eine typische Benutzer-Optionsdatei:

@example
[client]
# Folgendes Passwort wird an alle Standard-MySQL-Clients geschickt:
password=mein_password

[mysql]
no-auto-rehash
set-variable = connect_timeout=2

[mysqlhotcopy]
interactive-timeout

@end example

@tindex .my.cnf Datei
Wenn Sie eine Quelldistribution haben, finden Sie Beispielkonfigurationen
in den Dateien mit Namen @file{my-xxxx.cnf} im
@file{Support-files}-Verzeichnis. Wenn Sie eine Binärdistribution haben,
suchen Sie im @file{DIR/support-files}-Verzeichnis, wobei @code{DIR} der
Pfadname zum MySQL-Installationsverzeichnis ist (typischerweise
@file{/usr/local/mysql}). Aktuell finden Sie dort beispielhafte
Konfigurationsdateien für kleine, mittlere, große und sehr große Systeme.
Sie können @file{my-xxxx.cnf} in Ihr Heimatverzeichnis kopieren, um damit
zu experimentieren (benennen Sie die Kopie in @file{.my.cnf} um).

Alle MySQL-Clients, die Optionsdateien unterstützen, unterstützen folgende
Optionen:

@multitable @columnfractions .40 .60
@item --no-defaults @tab Keine Optionsdateien einlesen.
@item --print-defaults @tab Den Programmnamen und alle Optionen, die das Programm erhalten wird, ausgeben.
@item --defaults-file=voller-pfad-zur-vorgabe-datei @tab Nur die angegebene Konfigurationsdatei benutzen.
@item --defaults-extra-file=voller-pfad-zur-vorgabe-datei @tab Diese Konfigurationsdatei nach der globalen Konfigurationsdatei einlesen, aber vor der Benutzer-Konfigurationsdatei.
@end multitable

Beachten Sie, dass die oben aufgeführten Optionen auf der Kommandozeile
zuerst angegeben werden müssen, damit sie funktionieren!
@code{--print-defaults} kann jedoch direkt nach den
@code{--defaults-xxx-file}-Befehlen angegeben werden.

Hinweis für Entwickler: Optionsdatei-Handhabung ist schlicht dadurch
implementiert, dass alle übereinstimmenden Optionen verarbeitet werden
(das heißt, Optionen in der entsprechenden Gruppe), vor jeglichen
Kommandozeilen-Argumenten. Das funktioniert sehr gut bei Programmen, die
die letzte Instanz einer Option benutzen, die mehrfach festgelegt wurde.
Wenn Sie ein altes Programm benutzen, das mehrfach festgelegte Optionen auf
diese Art handhabt, aber keine Optionsdateien liest, müssen Sie nur zwei
Zeilen hinzufügen, um diese Fähigkeit hinzuzufügen. Sehen Sie im Quellcode
irgend eines Standard-MySQL-Clients nach, wie das gemacht wird.

In Shellskripts können Sie den @file{my_print_defaults}-Befehl benutzen, um
die Konfigurationsdateien zu parsen:

@example

shell> my_print_defaults client mysql
--port=3306
--socket=/tmp/mysql.sock
--no-auto-rehash
@end example

Die Ausgabe enthält alle Optionen für die Gruppen 'client' und 'mysql'.


@node Installing many servers, Multiple servers, Option files, Configuring MySQL
@c German node Viele Server installieren
@subsection Viele Server auf derselben Maschine installieren

@cindex Nach der Installation, mehrere Server
@cindex Mehrere Server installieren
@cindex Mehrere Server starten

In einigen Fällen brauchen Sie vielleicht viele verschiedene
@code{mysqld}-Daemons (Server), die auf derselben Maschine laufen.
Beispielsweise wollen Sie eine neue MySQL-Version zum Testen benutzen,
während gleichzeitig eine alte Version für die Produktion läuft, oder Sie
wollen verschiedenen Benutzern Zugriff auf verschiedene
@code{mysqld}-Server geben, die sie selbst verwalten.

Eine Möglichkeit, einen neuen Server laufen zu lassen, besteht darin, ihn
mit einem anderen Socket und einem anderen Port wie folgt zu starten:

@tindex @code{MYSQL_UNIX_PORT}-Umgebungsvariable
@tindex @code{MYSQL_TCP_PORT}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_UNIX_PORT}
@tindex Umgebungsvariable, @code{MYSQL_TCP_PORT}
@example
shell> MYSQL_UNIX_PORT=/tmp/mysqld-neu.sock
shell> MYSQL_TCP_PORT=3307
shell> export MYSQL_UNIX_PORT MYSQL_TCP_PORT
shell> scripts/mysql_install_db
shell> bin/safe_mysqld &
@end example

Der Umgebungsvariablen-Appendix beinhaltet eine Liste anderer
Umgebungsvariablen, die Sie benutzen können, um @code{mysqld} zu steuern.
@xref{Environment variables}.

Der oben gezeigte Weg ist die 'schnelle und schmutzige' Lösung, die man
üblicherweise zum Testen benutzt. Das nette daran ist, dass alle
Verbindungen, die Sie in obiger Shell aufbauen, automatisch an den neuen
laufenden Server weiter geleitet werden!

Wenn Sie dasselbe dauerhafter durchführen wollen, sollten Sie für jeden
Server eine Optionsdatei erzeugen. @xref{Option files}. In Ihrem
Startskript, das beim Hochfahren ausgeführt wird (mysql.server?) sollten
Sie für beide Server folgendes festlegen:

@code{safe_mysqld --default-file=pfad-zur-optionsdatei}

Zumindest folgende Optionen sollten für jeden Server unterschiedlich sein:

@table @code
@item port=#
@item socket=pfad
@item pid-file=pfad
@end table

Folgende Optionen sollten unterschiedlich sein, wenn sie benutzt werden:

@table @code
@item log=pfad
@item log-bin=pfad
@item log-update=pfad
@item log-isam=pfad
@item bdb-logdir=pfad
@end table

Wenn Sie mehr Performance erreichen wollen, können Sie auch folgendes
unterschiedlich festlegen:

@table @code
@item tmpdir=pfad
@item bdb-tmpdir=pfad
@end table

@xref{Command-line options}.

Wenn Sie binäre MySQL-Versionen installieren (.tar-Dateien) und sie mit
@code{./bin/safe_mysqld} starten, müssen Sie in den meisten Fällen
lediglich die @code{socket}- und @code{port}-Argumente in
@code{safe_mysqld} hinzufügen / ändern.




@node Multiple servers,  , Installing many servers, Configuring MySQL
@c German node Mehrere Server
@subsection Viele MySQL-Server auf derselben Maschine laufen lassen

@cindex Mehrere Server
@cindex Servers, mehrere
@cindex Laufen lassen, mehrere Server

Unter bestimmten Umständen wollen Sie vielleicht mehrere Server auf
derselben Maschine laufen lassen. Beispielsweise wollen Sie ein neues
MySQL-Release testen, Ihre bestehende Produktionseinrichtung aber
unangetastet lassen. Oder Sie sind ein Internet-Service-Provider, der
unabhängige MySQL-Installationen für verschiedene Kunden hat.

Wenn Sie mehrere Server laufen lassen wollen, ist es am einfachsten, die
Server mit unterschiedlichen TCP/IP-Ports und Socket-Dateien laufen zu
lassen, damit sie nicht beide auf demselben TCP/IP-Port oder derselben
Socket-Datei auf Verbindungen warten. @xref{mysqld_multi, ,
@code{mysqld_multi}}.

Nehmen wir einen existierenden Server an, der auf die existierende
Port-Nummer und Socket-Datei konfiguriert ist. Sie konfigurieren einen
neuen Server mit einem @code{configure}-Befehl, etwa wie folgt:

@example
shell> ./configure  --with-tcp-port=port_nummer \
             --with-unix-socket-path=datei \
             --prefix=/usr/local/mysql-3.22.9
@end example

Hier müssen @code{port_nummer} und @code{datei} anders als die
vorgabemäßigen Werte sein. Der @code{--prefix}-Wert sollte ein
Installationsverzeichnis festlegen, das anders ist als dasjenige, unter dem
die existierende MySQL-Installation liegt.

Sie können den Socket, der vom aktuell laufenden MySQL-Server benutzt wird,
mit folgendem Befehl feststellen:

@example
shell> mysqladmin -h hostname --port=port_nummer variables
@end example

Wenn Sie ``@code{localhost}'' als Hostnamen festlegen, benutzt
@code{mysqladmin} Unix-Sockets anstelle von TCP/IP.

Wenn Sie einen MySQL-Server auf dem Port laufen haben, den Sie benutzt
haben, bekommen Sie eine Liste der wichtigsten konfigurierbaren Variablen
in MySQL, inklusive des Socketnamens.

Sie müssen keinen neuen MySQL-Server kompilieren, nur um ihn mit einem
anderen Port und Socket zu starten. Sie können Port und Socket zur Laufzeit
als Optionen von @code{safe_mysqld} festlegen:

@example
shell> /pfad/zu/safe_mysqld --socket=datei --port=port_nummer
@end example

@code{mysqld_multi} kann ebenfalls @code{safe_mysqld} (oder @code{mysqld})
als Argument nehmen und die Optionen von einer Konfigurationsdatei an
@code{safe_mysqld} und weiter an @code{mysqld} durchreichen.

Wenn Sie den neuen Server mit demselben Datenbankverzeichnis laufen lassen
und Loggen angeschaltet haben, sollten Sie auch den Namen der Logdateien
für @code{safe_mysqld} mit @code{--log}, @code{--log-update} oder
@code{--log-slow-queries} festlegen. Ansonsten versuchen beide Server, in
dieselbe Logdatei zu schreiben.

@strong{ACHTUNG}: Normalerweise sollten Sie nie zulassen, dass zwei Server
Daten in derselben Datenbank aktualisieren! Wenn Ihr Betriebssystem kein
fehlerfreies System-Sperren (System Locking) unterstützt, führt das zu
unliebsamen Überraschungen!

Wenn Sie für den zweiten Server ein anderes Datenbankverzeichnis benutzen
wollen, können Sie das mit der @code{--datadir=path}-Option für
@code{safe_mysqld} angeben.

@strong{HINWEIS:} Mehrere MySQL-Server (@code{mysqld}) auf verschiedenen
Maschinen laufen lassen, die auf ein gemeinsames Datenverzeichnis über
@code{NFS} zugreifen, ist generell eine @strong{SCHLECHTE IDEE}! Das
Problem liegt darin, dass @code{NFS} zum Flaschenhals in Punkto
Geschwindigkeit wird, denn es ist nicht für solche Zwecke gedacht. Und
letztlich müssten Sie immer noch eine Lösung dafür finden, dass sich zwei
oder mehr @code{mysqlds} nicht in die Quere kommen. Momentan gibt es keine
Plattform, die mit 100%-iger Zuverlässigkeit Datei-Sperren (File Locking,
gewöhnlich mit dem @code{lockd}-Daemon) in jeder Situation durchführt.
Dennoch stellt @code{NFS} ein weiteres mögliches Risiko dar, denn es macht
es dem @code{lockd}-Daemon noch schwieriger, Datei-Sperren zu handhaben.
Machen Sie es sich also leicht und vergessen Sie diese Idee! Die
funktionierende Lösung ist, einen Computer mit einem Betriebssystem
einzusetzen, dass Threads effizient handhabt und mehrere Prozessoren hat.

Wenn Sie sich mit einem MySQL-Server verbinden wollen, der mit einem
anderen Port läuft als mit dem, der in Ihren Client kompiliert ist, können
Sie folgende Methoden benutzen:

@itemize @bullet
@item
Starten Sie den Client mit @code{--host 'hostname' --port=port_nummer}, um
sich über TCP/IP zu verbinden, oder mit @code{[--host localhost]
--socket=datei}, um sich über ein Unix-Socket zu verbinden.

@item
In Ihren C- oder Perl-Programmen können Sie die Port- oder Socket-Argumente
angeben, wenn Sie sich mit dem MySQL-Server verbinden.

@item
Wenn Sie das Perl-@code{DBD::mysql}-Modul benutzen, können Sie die Optionen
aus den MySQL-Optionsdateien lesen. @xref{Option files}.

@example
$dsn = "DBI:mysql:test;mysql_read_default_group=client;mysql_read_default_file=/usr/local/mysql/data/my.cnf"
$dbh = DBI->connect($dsn, $user, $password);
@end example

@item
@tindex MYSQL_UNIX_PORT-Umgebungsvariable
@tindex MYSQL_TCP_PORT-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_UNIX_PORT
@tindex Umgebungsvariable, MYSQL_TCP_PORT
Setzen Sie die @code{MYSQL_UNIX_PORT}- und
@code{MYSQL_TCP_PORT}-Umgebungsvariablen, so dass sie auf den Unix-Socket
und TCP/IP-Port zeigen, bevor Sie Ihre Clients starten. Wenn Sie
normalerweise eine speziellen Socket oder Port benutzen, sollten Sie die
Befehle zum Setzen dieser Umgebungsvariablen in Ihrer @file{.login}-Datei
unterbringen.
@xref{Environment variables}.

@item
@tindex .my.cnf Datei
Legen Sie den vorgabemäßigen Socket und TCP/IP-Port in der
@file{.my.cnf}-Datei in Ihrem Heimatverzeichnis fest.
@xref{Option files}.
@end itemize


@node Privilege system, User Account Management, Configuring MySQL, MySQL Database Administration
@c German node Berechtigungssystem
@section Allgemeine Sicherheitsthemen und das MySQL-Zugriffsberechtigungssystem

@cindex System, Sicherheit
@cindex Zugriffsberechtigungen
@cindex Berechtigungen, Zugriff
@cindex Sicherheitssystem
@cindex ACLs

MySQL hat ein fortgeschrittenes, aber nicht standardisiertes Sicherheits-
bzw. Berechtigungssystem. Dieser Abschnitt beschreibt, wie es funktioniert.



@menu
* General security::            
* Security::                    
* Privileges options::          
* What Privileges::             
* Privileges::                  
* Privileges provided::         
* Connecting::                  
* Connection access::           
* Request access::              
* Access denied::               
@end menu

@node General security, Security, Privilege system, Privilege system
@c German node Allgemeine Sicherheitsrichtlinien
@subsection Allgemeine Sicherheitsrichtlinien

Jeder, der MySQL auf einem Computer benutzt, der mit dem Internet verbunden
ist, sollte diesen Abschnitt lesen, um die gebräuchlichsten
Sicherheitsfehler zu vermeiden.

Wenn wir über Sicherheit sprechen, unterstreichen wir die Notwendigkeit,
den gesamten Server-Host (und nicht nur den MySQL-Server) gegen alle Arten
möglicher Angriffe abzusichern: Lauschangriffe, Änderungen (Altering),
Playback und Dienstverweigerung (Denial of Service). Dieser Abschnitt deckt
nicht alle Aspekte von Verfügbarkeit und Fehlertoleranz ab.

MySQL benutzt ein Sicherheitssystem, das auf Zugriffssteuerungslisten
(Access Control Lists, ACLs) für alle Verbindungen, Anfragen und sonstige
Operationen basiert, die ein Benutzer durchführen kann. Zusätzlich gibt es
einige Unterstützung für SSL-verschlüsselte Verbindungen zwischen
MySQL-Clients und -Servern. Viele der hier geschilderten Konzepte sind
überhaupt nicht spezifisch für MySQL, sondern beziehen sich auf fast alle
Applikationen.

Wenn Sie MySQL laufen lassen, sollten Sie möglichst immer folgende
Richtlinien beachten:

@itemize @bullet
@item
GEBEN SIE NIEMALS JEMANDEM AUSSER DEM MySQL-ROOT-BENUTZER ZUGRIFF AUF DIE
@code{user}-TABELLE IN DER @code{mysql}-DATENBANK! Das verschlüsselte
Passwort ist das echte Passwort in MySQL. Wenn Sie das in der the
@code{user}-Tabelle aufgeführte Passwort für einen gegebenen Benutzer
kennen, können Sie sich leicht als dieser Benutzer einloggen, wenn Sie
Zugriff auf den Host haben, der für dieses Benutzerkonto aufgeführt ist.

@item
Lernen Sie das MySQL-Zugriffsberechtigungssystem. Die @code{GRANT}- und 
@code{REVOKE}-Befehle werden benutzt, um den Zugriff auf MySQL zu steuern.
Gewähren Sie nicht mehr Zugriffsrechte als notwendig. Gewähren Sie niemals
Zugriffsrechte für alle Hosts.

Checkliste:
@itemize @minus
@item
Probieren Sie @code{mysql -u root}. Wenn es Ihnen gelingt, sich erfolgreich
mit dem Server zu verbinden, ohne nach einem Passwort gefragt zu werden,
haben Sie ein Problem, denn jeder kann sich als MySQL-@code{root}-Benutzer
mit dem Server verbinden und hat volle Berechtigungen! Lesen Sie in diesem
Fall noch einmal die MySQL-Installationsanweisungen durch und achten Sie
insbesondere auf den Teil, der sich mit dem Setzen des
@code{root}-Passworts beschäftigt.
@item
Benutzen Sie den Befehl @code{SHOW GRANTS} und prüfen Sie nach, wer Zugriff
auf was hat. Entfernen Sie die Berechtigungen, die nicht notwendig sind,
indem Sie den @code{REVOKE}-Befehl benutzen.
@end itemize
@item
Halten Sie keine Klartext-Passwörter in Ihrer Datenbank. Wenn Ihr Computer
kompromittiert wird, kann der Einbrecher die gesamte Liste von Passwörtern
nehmen und benutzen. Benutzen Sie statt dessen @code{MD5()} oder eine
andere Einweg-Hash-Funktion.
@item
Benutzen Sie keine Passwörter aus Lexika. Es gibt spezielle Programme, um
diese zu knacken. Selbst Passwörter wie ``xfish98'' sind sehr schlecht.
Viel besser ist ``duag98'', was dasselbe Wort ``fish'' enthält, aber um
eine Taste nach links auf einer QUERTZ-Tastatur verschoben. Eine weitere
Methode ist, etwas wie ``Mhall'' zu benutzen, was die ersten Buchstaben des
Satzes ``Mary had a little lamb'' enthält. Das läßt sich leicht merken und
eintippen, aber schwierig durch jemanden erraten, der es nicht kennt.
@item
Investieren Sie in eine Firewall. Diese schützt sie vor mindestens 50%
aller Exploits in jeglicher Software. Installieren Sie MySQL hinter einer
Firewall oder in einer entmilitarisierten Zone (Demilitarized Zone, DMZ).

Checkliste:
@itemize @minus
@item
Versuchen Sie, Ihre Ports vom Internet aus zu scannen, indem Sie ein Werkzeug
wie @code{nmap} benutzen. MySQL benutzt vorgabemäßig Port 3306. Dieser
Port sollte von nicht vertrauenswürdigen Hosts aus unerreichbar sein. Eine
weitere einfache Methode, um zu überprüfen, ob Ihr MySQL-Port offen ist
oder nicht, ist, den folgenden Befehl von einer entfernten Maschine aus zu
benutzen, wobei @code{server_host} der Hostname Ihres MySQL-Servers ist:

@example
shell> telnet server_host 3306
@end example

Wenn Sie eine Verbindung und einige sinnlose Zeichen erhalten, ist der Port
offen und sollte auf Ihrer Firewall oder Ihrem Router geschlossen werden,
sofern Sie nicht einen wirklich guten Grund haben, ihn offen zu halten.
Wenn @code{telnet} einfach hängt oder die Verbindung abgelehnt wird, ist
alles in Ordnung, der Port ist blockiert.
@end itemize

@item
Trauen Sie keinen Daten, die von Benutzern eingegeben werden. Sie können
versuchen, Ihren Code auszutricksen, indem Sie spezielle oder escapete
Zeichenfolgen in Web-Formulare, URLs oder sonstige Applikationen, die Sie
hergestellt haben, eingeben. Stellen Sie sicher, dass Ihre Applikation
sicher bleibt, wenn ein Benutzer etwas wie ``@code{; DROP DATABASE
mysql;}'' eingibt. Das ist ein extremes Beispiel, aber große
Sicherheitslücken und Datenverlust können eintreten, wenn ein Hacker
ähnliche Techniken benutzt und Sie nicht darauf vorbereitet sind.

Denken Sie auch daran, numerische Daten zu überprüfen. Ein häufiger Fehler
besteht darin, nur Zeichenketten zu schützen. Manchmal denken Leute, dass
eine Datenbank, die nur öffentlich zugängliche Daten enthält, nicht
geschützt werden muss. Das stimmt nicht. Auf solche Datenbanken können
zumindest Dienstverweigerungsangriffe (Denial-of-Service-Attacken)
durchgeführt werden. Die einfachste Art, sich vor dieser Art von Angriffen
zu schützen, ist, Apostrophe um numerische Konstanten herum zu benutzen:
@code{SELECT * FROM tabelle WHERE ID='234'} statt @code{SELECT * FROM
tabelle WHERE ID=234}. MySQL wandelt diese Zeichenkette automatisch in eine
Zahl um und entfernt alle nicht-numerischen Zeichen aus ihr.

Checkliste:
@itemize @minus
@item
Alle Web-Applikationen:
@itemize @bullet
@item
Versuchen Sie, @samp{'} und @samp{"} in alle Ihr Web-Formulare einzugeben.
Wenn Sie irgend welche MySQL-Fehler erhalten, untersuchen Sie das Problem
unverzüglich!
@item
Versuchen Sie, jedwede dynamischen URLs zu ändern, indem Sie @code{%22}
(@samp{"}), @code{%23} (@samp{#}) und @code{%27} (@samp{'}) zu den URLs
hinzufügen.
@item
Versuchen Sie, Datentypen in dynamischen URLs von numerischen zu
Zeichentypen zu ändern, die Zeichen aus den vorherigen Beispielen
enthalten. Ihre Applikation sollte gegen solche und ähnliche Angriffe
sicher sein.
@item
Versuchen Sie Buchstaben, Leerzeichen und Sonderzeichen anstelle von Zahlen
in numerische Felder einzugeben. Ihre Applikation sollte diese entfernen,
bevor sie sie MySQL übergibt, und Ihre Applikation sollte einen Fehler
erzeugen. Es ist sehr gefährlich, nicht geprüfte Werte an MySQL zu
übergeben!
@item
Überprüfen Sie Datengrößen, bevor Sie sie an MySQL übergeben.
@item
Überlegen Sie, ob es sinnvoll ist, dass sich Ihre Applikation mit einem
anderen Benutzernamen mit der Datenbank verbindet als mit dem, den Sie für
Verwaltungszwecke benutzen. Geben Sie Applikationen nicht mehr
Zugriffsberechtigungen als sie brauchen.
@end itemize
@item
Benutzer von PHP:
@itemize @bullet
@item Sehen Sie sich die @code{addslashes()}-Funktion an.
Ab PHP 4.0.3 ist eine @code{mysql_escape_string()}-Funktion verfügbar, die
auf der Funktion mit demselben Namen in der MySQL-C-API basiert.
@end itemize
@item
Benutzer der MySQL-C-API:
@itemize @bullet
@item Sehen Sie sich den @code{mysql_escape_string()}-API-Aufruf an.
@end itemize
@item
Benutzer von MySQL++:
@itemize @bullet
@item Sehen Sie sich die @code{escape}- und @code{quote}-Modifier für
Query-Streams an.
@end itemize
@item
Benutzer der Perl-DBI:
@itemize @bullet
@item Sehen Sie sich die @code{quote()}-Methode an oder benutzen Sie
Platzhalter.
@end itemize
@item
Benutzer von Java-JDBC:
@itemize @bullet
@item Benutzen Sie ein @code{PreparedStatement}-Objekt und Platzhalter.
@end itemize
@end itemize

@item
Übermitteln Sie keine Klartextdaten (unverschlüsselte Daten) über das
Internet. Diese Daten sind für jeden zugänglich, der Zeit und Möglichkeit
hat, sie abzuhören und sie für die eigenen Zwecke zu benutzen. Benutzen Sie
statt dessen ein verschlüsseltes Protokoll wie SSL oder SSH. MySQL
unterstützt ab Version 4.0.0 interne SSL-Verbindungen.
SSH-Port-Forwarding kann benutzt werden, um einen verschlüsselten (und
komprimierten) Kommunikationstunnel zu erzeugen.
@item
Lernen Sie die Benutzung der @code{tcpdump}- und @code{strings}-Utilities.
In den meisten Fällen können Sie mit einem Befehl wie dem folgenden
feststellen, ob MySQL-Datenströme verschlüsselt sind oder nicht:

@example
shell> tcpdump -l -i eth0 -w - src or dst port 3306 | strings
@end example

(Das funktioniert unter Linux und sollte mit kleineren Änderungen auf
anderen Systemen funktionieren.) Achtung: Wenn Sie keine Daten sehen,
heißt das nicht immer, dass sie verschlüsselt sind. Wenn Sie hohe
Sicherheit benötigen, sollten Sie sich mit einem Sicherheitsexperten in
Verbindung setzen.
@end itemize


@node Security, Privileges options, General security, Privilege system
@c German node Sicherheit
@subsection Wie Sie MySQL gegen Cracker sicher machen

@cindex Cracker, Sicherheit gegen
@cindex Sicherheit, gegen Cracker

Wenn Sie sich mit einem MySQL-Server verbinden, sollten Sie normalerweise
ein Passwort benutzen. Das Passwort wird nicht als Klartext über die
Verbindung übermittelt. Allerdings ist der Verschlüsselungsalgorithmus
nicht sehr stark, so dass ein cleverer Angreifer mit einiger Mühe das
Passwort knacken kann, wenn er in der Lage ist, den Verkehr zwischen Client
und Server abzuhören. Wenn die Verbindung zwischen Client und Server über
ein nicht vertrauenswürdiges Netzwerk geht, sollten Sie einen SSH-Tunnel
benutzen, um die Kommunikation zu verschlüsseln.

Jede sonstige Information wird als Klartext übermittelt, die von jedem
gelesen werden kann, der in der Lage ist, die Verbindung abzuhören. Wenn
Sie das beunruhigt, können Sie das komprimierte Protokoll benutzen (ab
MySQL-Version 3.22), um so etwas zu erschweren. Um die Dinge noch sicherer
zu machen, sollten Sie @code{ssh} benutzen. Sie finden einen Open-Source-
@code{ssh}-Client auf @uref{http://www.openssh.org} und einen kommerziellen
@code{ssh}-Client auf @uref{http://www.ssh.com}. Mit diesen erhalten Sie
eine verschlüsselte TCP/IP-Verbindung zwischen einem MySQL-Server und einem
MySQL-Client.

Um ein MySQL-System sicher zu machen, sollten Sie auf jeden Fall folgende
Vorschläge in Betracht ziehen:

@itemize @bullet
@item
Benutzen Sie Passwörter für alle MySQL-Benutzer. Bedenken Sie, dass sich
jeder beliebige als andere Person einloggen kann, und zwar so einfach wie
@code{mysql -u anderer_benutzer db_name}, wenn @code{anderer_benutzer} kein
Passwort hat. Es ist ein normales Verhalten bei
Client-Server-Applikationen, dass der Client einen beliebigen Benutzernamen
angeben kann. Sie können das Passwort für alle Benutzer ändern, indem Sie
das @code{mysql_install_db}-Skript editieren, bevor Sie es laufen lassen,
oder nur das Passwort für den MySQL-@code{root}-Benutzer, wie folgt:

@example
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('neues_passwort')
           WHERE user='root';
mysql> FLUSH PRIVILEGES;
@end example

@item
Lassen Sie den MySQL-Daemon nicht als Unix-@code{root}-Benutzer laufen. Das
ist sehr gefährlich, denn jeder Benutzer mit @code{FILE}-Berechtigung ist
dann in der Lage, Dateien als @code{root} zu erzeugen (zum Beispiel
@code{~root/.bashrc}). Um das zu verhindern, weigert sich @code{mysqld},
als @code{root} zu laufen, es sei denn, das wird direkt durch die
@code{--user=root}-Option angegeben.

@code{mysqld} kann unter einem gewöhnlichen Benutzer ohne besondere Rechte
laufen. Sie können auch einen neuen Unix-Benutzer @code{mysql} anlegen, um
alles noch sicherer zu machen. Wenn Sie @code{mysqld} als ein anderer
Unix-Benutzer laufen lassen, müssen Sie nicht den @code{root}-Benutzernamen
in der @code{user}-Tabelle ändern, denn MySQL-Benutzernamen haben nichts
mit den Unix-Benutzernamen zu tun. Um @code{mysqld} als anderer
Unix-Benutzer zu starten, fügen Sie eine @code{user}-Zeile hinzu, die den
Benutzernamen zur @code{[mysqld]}-Gruppe der
@file{/etc/my.cnf}-Optionsdatei oder der @file{my.cnf}-Optionsdatei im
Daten-Verzeichnis des Servers hinzufügt. Beispiel:

@example
[mysqld]
user=mysql
@end example

Das bewirkt, dass der Server als der festgelegte Benutzer gestartet wird,
egal ob Sie ihn manuell oder mit @code{safe_mysqld} oder
@code{mysql.server} starten. Weitere Details finden Sie unter @ref{Privilege changes, , MySQL-Benutzer ändern}.

@item
Unterstützen Sie keine Symlinks auf Tabellen (das kann mit der
@code{--skip-symlink}-Option abgeschaltet werden). Das ist insbesondere
wichtig, wenn Sie @code{mysqld} als Root laufen lassen, weil jeder, der
Schreibzugriff auf das mysqld-Daten-Verzeichnis hat, dann jede Datei im
System zerstören könnte!
@xref{Symbolic links to tables}.

@item
Überprüfen Sie, dass der Unix-Benutzer, der @code{mysqld} laufen läßt, der
einzige Benutzer mit Lese-/Schreibzugriffen auf die Datenbankverzeichnisse
ist.

@item
Geben Sie nicht allen Benutzern das @strong{process}-Zugriffsrecht. Die
Ausgabe von @code{mysqladmin processlist} zeigt den Text der aktuell
ausgeführten Anfragen, so dass jeder, der diesen Befehl ausführen darf, in
der Lage wäre, eine Anfrage eines anderen Benutzers wie @code{UPDATE user
SET password=PASSWORD('not_secure')} einzusehen.

@code{mysqld} reserviert eine zusätzliche Verbindung für Benutzer, die das
@strong{process}-Zugriffsrecht haben, so dass sich ein
MySQL-@code{root}-Benutzer einloggen und Dinge überprüfen kann, selbst wenn
alle normalen Verbindungen in Benutzung sind.

@item
Geben Sie nicht allen Benutzern das @strong{file}-Zugriffsrecht. Jeder
Benutzer, der dieses Zugriffsrecht hat, kann irgendwo im Dateisystem
Dateien mit den Rechten des the @code{mysqld}-Daemons schreiben! Um das
etwas sicherer zu machen, sind alle Dateien, die mit @code{SELECT ... INTO
OUTFILE} erzeugt werden, für jeden lesbar und können keine existierenden
Dateien überschreiben.

@tindex /etc/passwd
Das @strong{file}-Zugriffsrecht kann auch benutzt werden, um jede Datei zu
lesen, auf die der Unix-Benutzer Zugriff hat, als der der Server läuft. Das
könnte zum Beispiel durch Benutzung von @code{LOAD DATA} missbraucht
werden, um @file{/etc/passwd} in eine Tabelle zu laden, die anschließend
mit @code{SELECT} gelesen wird.

@item
Wenn Sie Ihrem DNS nicht trauen, sollten Sie IP-Nummern anstelle von
Hostnamen in den Berechtigungstabellen verwenden. In jedem Fall sollten Sie
sehr vorsichtig damit sein, Einträge in Berechtigungstabellen vorzunehmen,
die Hostnamen mit Platzhaltern (Wildcards) verwenden!

@item
Wenn Sie die Anzahl der Verbindungen für einen einzelnen Benutzer
beschränken wollen, können Sie das tun, indem Sie die
@code{max_user_Verbindungen}-Variable in @code{mysqld} setzen.
@end itemize



@node Privileges options, What Privileges, Security, Privilege system
@c German node Berechtigungsoptionen
@subsection Startoptionen für @code{mysqld} in Bezug auf Sicherheit

Folgende @code{mysqld}-Optionen berühren Sicherheitsaspekte:

@table @code
@item --safe-show-database
Mit dieser Option gibt @code{SHOW DATABASES} nur die Datenbanken zurück,
für die der Benutzer irgend welche Rechte hat.

@item --safe-user-create
Wenn das angeschaltet ist, kann ein Benutzer keine neuen Benutzer mit dem
@code{GRANT}-Befehl anlegen, wenn der kein @code{INSERT}-Zugriffsrecht auf
die @code{mysql.user}-Tabelle hat. Wenn Sie dem Benutzer nur das Recht
geben wollen, neue Benutzer mit den Berechtigungen anzulegen, die er
vergeben darf, sollten Sie ihm folgende Berechtigung geben:

@example
GRANT INSERT(benutzer) on mysql.user to 'benutzer'@'hostname';
@end example

Das stellt sicher, dass der Benutzer keine Berechtigungsspalten direkt
ändern kann, sondern dafür den @code{GRANT}-Befehl benutzen muss.

@item --skip-grant-tables
Diese Option veranlasst den Server, das Berechtigungssystem überhaupt nicht
zu benutzen. Das gibt jedem @emph{vollen Zugriff} auf alle Datenbanken!
(Einen laufenden Server können Sie veranlassen, die Berechtigungstabellen
erneut zu verwenden, indem Sie @code{mysqladmin flush-privileges} oder
@code{mysqladmin reload} ausführen.)

@item --skip-name-resolve
Hostnamen werden nicht aufgelöst. Alle @code{Host}-Spaltenwerte in den
Berechtigungstabellen müssen IP-Nummern oder @code{localhost} sein.

@item --skip-networking
Keine TCP/IP-Verbindungen über das Netzwerk zulassen. Alle Verbindungen zu
@code{mysqld} müssen über Unix-Sockets gemacht werden. Diese Option ist
ungeeignet für Systeme, die MIT-pThreads benutzen, weil das
MIT-pThreads-Paket keine Unix-Sockets unterstützt.

@item --skip-show-database
Mit dieser Option gibt das @code{SHOW DATABASES}-Statement nichts zurück.

@end table


@node What Privileges, Privileges, Privileges options, Privilege system
@c German node Welche Berechtigungen
@subsection Was das Berechtigungssystem macht

@cindex System, Berechtigungen
@cindex Berechtigungssystem
@cindex Passwörter, Sicherheit

Die primäre Funktion des MySQL-Berechtigungssystem ist, einen Benutzer zu
authentifizieren, der sich von einem gegebenen Host aus verbindet, und
diesen Benutzer Berechtigungen auf eine Datenbank zuzuordnen, wie
@strong{select}, @strong{insert}, @strong{update} und @strong{delete}.

Zusätzliche Funktionalität beinhaltet die Möglichkeit, einen anonymen
Benutzer anzulegen und Berechtigungen für MySQL-spezifische Funktionen wie
@code{LOAD DATA INFILE} und für administrative Operationen zu gewähren.


@node Privileges, Privileges provided, What Privileges, Privilege system
@c German node Berechtigungen
@subsection Wie das Berechtigungssystem funktioniert

@cindex Berechtigungssystem, Beschreibung

Das MySQL-Berechtigungssystem stellt sicher, dass alle Benutzer nur genau
die Dinge tun dürfen, zu denen sie berechtigt sind. Wenn Sie sich mit einem
MySQL-Server verbinden, wird Ihre Identität @strong{durch den Host, von dem
Sie sich aus verbinden,} festgelegt und @strong{durch den Benutzernamen,
den Sie angeben}. Das System gewährt Berechtigungen gemäß Ihrer Identität
und gemäß dem, @strong{was Sie tun wollen}.

MySQL zieht sowohl Hostnamen als auch Benutzernamen heran, um Sie zu
identifizieren, weil es kaum Grund gibt anzunehmen, dass ein gegebener
Benutzername derselben Person woanders auf dem Internet gehört. So muss zum
Beispiel der Benutzer @code{bill}, der sich von @code{whitehouse.gov} aus
verbindet, nicht notwendigerweise dieselbe Person sein, die sich als
Benutzer @code{bill} von @code{microsoft.com} aus verbindet.
MySQL erlaubt Ihnen deshalb, Benutzer auf unterschiedlichen Hosts
auseinander zu halten, die zufällig denselben Namen haben: Sie können
@code{bill} einen Satz von Berechtigungen für Verbindungen von
@code{whitehouse.gov} und einen anderen Satz von Berechtigungen für
Verbindungen von @code{microsoft.com} aus gewähren.

Die MySQL-Zugriffskontrolle läuft in zwei Phasen ab:

@itemize @bullet
@item
Phase 1: Der Server überprüft, ob Sie das Recht haben, sich verbinden zu
können.

@item
Phase 2: Angenommen, Sie haben das Recht, sich zu verbinden, dann überprüft
der Server jede Anfrage, die Sie absetzen, um festzustellen, ob Sie
ausreichende Rechte haben, um diese auszuführen. Wenn Sie zum Beispiel
Zeilen aus einer Tabellen in einer Datenbank auswählen oder eine Tabelle in
einer Datenbank löschen, stellt der Server sicher, dass Sie die
@strong{select}-Berechtigung für die Tabelle bzw. die
@strong{drop}-Berechtigung für die Datenbank haben.
@end itemize

Der Server benutzt die @code{user}-, @code{db}- und @code{host}-Tabellen in
der @code{mysql}-Datenbank in beiden Phasen der Zugriffskontrolle. Die
Felder in diesen Berechtigungstabellen sind unten dargestellt:

@multitable @columnfractions .2 .25 .25 .25
@item @strong{Tabellenname} @tab @code{user} @tab @code{db} @tab @code{host}

@item @strong{Geltungsbereichs-Felder} @tab @code{Host}          @tab @code{Host}        @tab @code{Host}
@item @tab @code{User}          @tab @code{Db}          @tab @code{Db}
@item @tab @code{Password}      @tab @code{User}        @tab

@item @strong{Berechtigungs-Felder} @tab @code{Select_priv} @tab @code{Select_priv} @tab @code{Select_priv}
@item @tab @code{Insert_priv}   @tab @code{Insert_priv} @tab @code{Insert_priv}
@item @tab @code{Update_priv}   @tab @code{Update_priv} @tab @code{Update_priv}
@item @tab @code{Delete_priv}   @tab @code{Delete_priv} @tab @code{Delete_priv}
@item @tab @code{Index_priv}    @tab @code{Index_priv}  @tab @code{Index_priv}
@item @tab @code{Alter_priv}    @tab @code{Alter_priv}  @tab @code{Alter_priv}
@item @tab @code{Create_priv}   @tab @code{Create_priv} @tab @code{Create_priv}
@item @tab @code{Drop_priv}     @tab @code{Drop_priv}   @tab @code{Drop_priv}
@item @tab @code{Grant_priv}    @tab @code{Grant_priv}  @tab @code{Grant_priv}
@item @tab @code{References_priv} @tab                  @tab
@item @tab @code{Reload_priv}   @tab                    @tab
@item @tab @code{Shutdown_priv} @tab                    @tab
@item @tab @code{Process_priv}  @tab                    @tab
@item @tab @code{File_priv}     @tab                    @tab
@end multitable

In der zweiten Phase der Zugriffskontrolle (Anfrage-Verifikation), zieht
der Server gegebenenfalls zusätzlich die @code{tables_priv}- und
@code{columns_priv}-Tabellen heran, falls Ihre Anfrage Tabellen betrifft.
Die Felder in diesen Tabellen sind unten dargestellt:

@multitable @columnfractions .2 .25 .25
@item @strong{Tabellenname}   @tab @code{tables_priv} @tab @code{columns_priv}

@item @strong{Geltungsbereichs-Felder} @tab @code{Host}        @tab @code{Host}
@item                       @tab @code{Db}          @tab @code{Db}
@item                       @tab @code{User}        @tab @code{User}
@item                       @tab @code{Table_name}  @tab @code{Table_name}
@item                       @tab                    @tab @code{Column_name}

@item @strong{Berechtigungs-Felder} @tab @code{Table_priv}   @tab @code{Column_priv}
@item                           @tab @code{Column_priv}  @tab

@item @strong{Sonstige Felder} @tab @code{Timestamp}   @tab @code{Timestamp}
@item                       @tab @code{Grantor}     @tab
@end multitable

Jede Berechtigungstabelle enthält Geltungsbereichsfelder und
Berechtigungsfelder.

Geltungsbereichsfelder legen den Geltungsbereich jedes Eintrags in den
Tabellen fest, das heißt, der Kontext, für den der Eintrag gilt. So würde
zum Beispiel ein @code{user}-Tabelleneintrag mit @code{Host}- und
@code{User}-Werten von @code{'thomas.loc.gov'} und @code{'bob'} benutzt
werden, um Verbindungen zum Server zu authentifizieren, die von @code{bob}
vom Host @code{thomas.loc.gov} gemacht werden. In ähnlicher Weise bewirkt
ein @code{db}-Tabelleneintrag in die Felder @code{Host}, @code{User} und
@code{Db} mit @code{'thomas.loc.gov'}, @code{'bob'} und @code{'reports'},
dass diese benutzt werden, wenn sich @code{bob} vom Host
@code{thomas.loc.gov} verbindet und auf die @code{reports}-Datenbank zugreift. 
Die @code{tables_priv}- und @code{columns_priv}-Tabellen enthalten
Geltungsbereichsfelder, die Tabellen oder Tabellen-Spalten-Kombinationen
angeben, auf die sich der jeweilige Eintrag bezieht.

@cindex Groß-/Kleinschreibung, bei der Zugriffsprüfung
Für Zwecke der Zugriffsprüfung sind Vergleiche von @code{Host}-Werten
unabhängig von der verwendeten Groß-/Kleinschreibung. @code{User},
@code{Password}, @code{Db} und @code{Table_name}-Werte sind abhängig von
der verwendeten Groß-/Kleinschreibung. @code{Column_name}-Werte sind ab
MySQL-Version 3.22.12 unabhängig von der verwendeten
Groß-/Kleinschreibung.

Berechtigungsfelder zeigen die Berechtigungen an, die durch den
Tabelleneintrag gewährt werden, das heißt, welche Operationen durchgeführt
werden können. Der Server kombiniert die Informationen in den verschiedenen
Berechtigungstabellen, um daraus eine komplette Beschreibung der
Berechtigungen des Benutzers zu formulieren. Die Regeln, nach denen hierbei
vorgegangen wird, sind in @ref{Request access} beschrieben.

Geltungsbereichsfelder sind Zeichenketten, die wie unten dargestellt
deklariert werden. Der Vorgabewert für jedes Feld ist die leere
Zeichenkette:

@multitable @columnfractions .15 .15 .7
@item @strong{Feldname} @tab @strong{Typ}
@item @code{Host}         @tab @code{CHAR(60)}
@item @code{User}         @tab @code{CHAR(16)}
@item @code{Password}     @tab @code{CHAR(16)}
@item @code{Db}           @tab @code{CHAR(64)} @tab (@code{CHAR(60)} für
die @code{tables_priv}- und @code{columns_priv}-Tabellen)
@item @code{Table_name}   @tab @code{CHAR(60)}
@item @code{Column_name}  @tab @code{CHAR(60)}
@end multitable

In den @code{user}-, @code{db}- und @code{host}-Tabellen werden alle Felder
als @code{ENUM('N','Y')} deklariert. Jedes Feld kann einen Wert von
@code{'N'} oder @code{'Y'} haben. Der Vorgabewert ist @code{'N'}.

In den @code{tables_priv}- und @code{columns_priv}-Tabellen werden Felder
als @code{SET}-Felder deklariert:

@multitable @columnfractions .2 .2 .6
@item @strong{Tabellenname} @tab @strong{Feldname} @tab @strong{Mögliche Set-Elemente}
@item @code{tables_priv} @tab @code{Table_priv} @tab @code{'Select', 'Insert',
'Update', 'Delete', 'Create', 'Drop', 'Grant', 'Referenzs', 'Index', 'Alter'}
@item @code{tables_priv} @tab @code{Column_priv} @tab @code{'Select', 'Insert',
'Update', 'References'}
@item @code{columns_priv} @tab @code{Column_priv} @tab @code{'Select', 'Insert',
'Update', 'References'}
@end multitable

Kurz gesagt benutzt der Server die Berechtigungstabellen wie folgt:

@itemize @bullet
@item
Das @code{user}-Tabellenbereichsfeld legt fest, ob eingehende Verbindungen
zugelassen oder abgewiesen werden. Bei zugelassenen Verbindungen zeigen
Berechtigungen, die in der @code{user}-Tabelle vergeben sind, die globalen
(Superuser-) Rechte des Benutzers an. Diese Berechtigungen treffen auf
@strong{alle} Datenbanken auf dem Server zu.

@item
Die @code{db}- und @code{host}-Tabellen werden zusammen benutzt:

@itemize @minus
@item
Die Geltungsbereichsfelder der @code{db}-Tabelle legen fest, welche
Benutzer auf welche Datenbanken von welchen Hosts aus zugreifen können. Die
Berechtigungsfelder legen fest, welche Operationen zugelassen sind.

@item
Die @code{host}-Tabelle wird als Erweiterung der @code{db}-Tabelle benutzt,
wenn Sie wollen, dass ein gegebener @code{db}-Tabelleneintrag auf
verschiedene Hosts zutrifft. Wenn Sie zum Beispiel wollen, dass ein
Benutzer eine Datenbank von mehreren Hosts in Ihrem Netzwerk aus benutzen
kann, lassen Sie den @code{Host}-Wert in der @code{db}-Tabelle des
Benutzers leer, und füllen dann die @code{host}-Tabelle mit einem Eintrag
für jeden dieser Hosts. Dieser Mechanismus ist ausführlicher in
@ref{Request access} beschrieben.
@end itemize

@item
Die @code{tables_priv}- und @code{columns_priv}-Tabellen sind der
@code{db}-Tabelle ähnlich, aber feinkörniger: Sie beziehen sich auf
Tabellen- und Spaltenebenen und nicht auf Datenbankebene.
@end itemize

Beachten Sie, dass die Verwaltungsberechtigungen (@strong{reload},
@strong{shutdown} usw.) nur in der @code{user}-Tabelle festgelegt werden.
Das liegt daran, dass Verwaltungsoperationen Operationen auf dem Server
selbst sind und nicht Datenbank-spezifisch, so dass es keinen Grund gibt,
solche Berechtigungen in den anderen Berechtigungstabellen aufzuführen. So
muss nur die @code{user}-Tabelle untersucht werden um festzustellen, ob man
Verwaltungsoperationen durchführen kann oder nicht.

Das @strong{file}-Zugriffsrecht wird auch nur in der @code{user}-Tabelle
festgelegt. Es ist als solches keine Verwaltungsberechtigung, aber Ihre
Möglichkeit, Dateien auf dem Server zu lesen oder zu schreiben, ist
unabhängig von der Datenbank, auf die Sie zugreifen.

Der @code{mysqld}-Server liest die Inhalte der Berechtigungstabellen
einmal, und zwar beim Start. Änderungen in den Berechtigungstabellen werden
wirksam wie in @ref{Privilege changes} geschildert.

Wenn Sie die Inhalte der Berechtigungstabellen ändern, sollten Sie
sicherstellen, dass Ihre Änderungen Berechtigungen einführen, die Sie so
haben wollen. Hilfe bei der Diagnose von Problemen finden Sie unter
@ref{Access denied}. Hinweise zu Sicherheitsthemen finden Sie unter
@pxref{Security}.

Ein nützliches Diagnosetool ist das @code{mysqlaccess}-Skript, das Yves
Carlier für die MySQL-Distribution bereit gestellt hat. Rufen Sie
@code{mysqlaccess} mit der @code{--help}-Option auf, um herauszufinden, wie
es funktioniert. Beachten Sie, dass @code{mysqlaccess} den Zugriff nur
anhand der @code{user}-, @code{db}- und @code{host}-Tabellen überprüft. Es
überprüft keine Tabellen- oder Spaltenebenen-Berechtigungen.


@node Privileges provided, Connecting, Privileges, Privilege system
@c German node Zur Verfügung gestellte Berechtigungen
@subsection Von MySQL zur Verfügung gestellte Berechtigungen

@cindex Berechtigungsinformation, Speicherort

Informationen über Benutzerberechtigungen sind in den @code{user}-,
@code{db}-, @code{host}-, @code{tables_priv}- und
@code{columns_priv}-Tabellen in der @code{mysql}-Datenbank gespeichert (das
heißt in der Datenbank, die @code{mysql} heißt). Der MySQL-Server liest
die Inhalte dieser Tabellen, wenn er startet, und in den Fällen, die unter
@ref{Privilege changes} geschildert sind.

Die Namen, die in diesem Handbuch benutzt werden, um auf die Berechtigungen
zu verweisen, die MySQL zur Verfügung stellt, sind unten dargestellt,
zusammen mit den Tabellenspaltennamen, die jeder Berechtigung in the
Berechtigungstabellen zugeordnet sind, und dem Kontext, auf den die
Berechtigung zutrifft.

@multitable @columnfractions .15 .25 .6
@item @strong{Berechtigung}   @tab @strong{Spalte}   @tab @strong{Kontext}
@item @strong{select}      @tab @code{Select_priv}   @tab Tabellen
@item @strong{insert}      @tab @code{Insert_priv}   @tab Tabellen
@item @strong{update}      @tab @code{Update_priv}   @tab Tabellen
@item @strong{delete}      @tab @code{Delete_priv}   @tab Tabellen
@item @strong{index}       @tab @code{Index_priv}    @tab Tabellen
@item @strong{alter}       @tab @code{Alter_priv}    @tab Tabellen
@item @strong{create}      @tab @code{Create_priv}   @tab Datenbanken, Tabellen oder Indexe
@item @strong{drop}        @tab @code{Drop_priv}     @tab Datenbanken oder Tabellen
@item @strong{grant}       @tab @code{Grant_priv}    @tab Datenbanken oder Tabellen
@item @strong{References}  @tab @code{References_priv} @tab Datenbanken oder Tabellen
@item @strong{reload}      @tab @code{Reload_priv}   @tab Serververwaltung
@item @strong{shutdown}    @tab @code{Shutdown_priv} @tab Serververwaltung
@item @strong{process}     @tab @code{Process_priv}  @tab Serververwaltung
@item @strong{file}        @tab @code{File_priv}     @tab Dateizugriff auf den Server
@end multitable

Die @strong{select}-, @strong{insert}-, @strong{update}- und
@strong{delete}-Berechtigungen erlauben Ihnen, Operationen auf Zeilen in
existierenden Tabellen in einer Datenbank durchzuführen.

@code{SELECT}-Statements erfordern die @strong{select}-Berechtigung nur
dann, wenn tatsächlich Zeilen aus einer Tabelle abgerufen werden. Sie
können bestimmte @code{SELECT}-Statements selbst ohne Berechtigung
durchführen, um auf jede der Datenbanken auf dem Server zuzugreifen.
Beispielsweise könnten Sie den @code{mysql}-Client als einfachen
Taschenrechner benutzen:

@example
mysql> SELECT 1+1;
mysql> SELECT PI()*2;
@end example

Die @strong{index}-Berechtigung erlaubt Ihnen, Indexe zu erzeugen oder zu
entfernen.

Die @strong{alter}-Berechtigung erlaubt Ihnen, @code{ALTER TABLE} zu
benutzen.

Die @strong{create}- und @strong{drop}-Berechtigungen erlauben Ihnen, neue
Datenbanken und Tabellen zu erzeugen oder bestehende Datenbanken und
Tabellen zu entfernen.

Denken Sie daran, dass ein Benutzer, dem Sie die @strong{drop}-Berechtigung
für die @code{mysql}-Datenbank gewähren, in der Lage ist, die Datenbank zu
löschen, in der die MySQL-Zugriffsberechtigungen gespeichert sind!

Die @strong{grant}-Berechtigung erlaubt Ihnen, die Berechtigungen, die Sie
selbst besitzen, an andere Benutzer zu vergeben.

Die @strong{file}-Berechtigung erlaubt Ihnen, Dateien auf dem Server zu
lesen und zu schreiben, wenn Sie die @code{LOAD DATA INFILE}- und
@code{SELECT ... INTO OUTFILE}-Statements benutzen. Jeder Benutzer, dem
diese Berechtigung gewährt wurde, kann jedwede Datei lesen oder schreiben,
die der MySQL-Server lesen oder schreiben darf.

Die restlichen Berechtigungen werden für Verwaltungsoperationen benutzt,
die mit dem @code{mysqladmin}-Programm durchgeführt werden. Die unten
stehende Tabelle zeigt, welche @code{mysqladmin}-Befehle mit jeder
Verwaltungsberechtigung ausgeführt werden können:

@multitable @columnfractions .15 .85
@item @strong{Berechtigung}  @tab @strong{Befehle, die dem Berechtigten erlaubt sind}
@item @strong{reload}     @tab @code{reload}, @code{refresh},
@code{flush-privileges}, @code{flush-hosts}, @code{flush-logs} und
@code{flush-tables}
@item @strong{shutdown}   @tab @code{shutdown}
@item @strong{process}    @tab @code{processlist}, @code{kill}
@end multitable

Der @code{reload}-Befehl weist den Server an, die Berechtigungstabellen neu
einzulesen. Der @code{refresh}-Befehl schreibt alle Tabellen auf Platte
(flush) und öffnet und schließt die Log-Dateien. @code{flush-privileges}
ist ein Synonym für @code{reload}. Die anderen @code{flush-*}-Befehle
führen Funktionen aus, die @code{refresh} ähnlich sind, aber im Umfang
beschränkter und daher in einigen Fällen zu bevorzugen. Wenn Sie zum
Beispiel nur die Log-Dateien flushen wollen, ist @code{flush-logs}
@code{refresh} vorzuziehen.

Der @code{shutdown}-Befehl fährt den Server herunter.

Der @code{processlist}-Befehl zeigt Informationen über die Threads an, die
im Server ausgeführt werden. Der @code{kill}-Befehl killt Server-Threads.
Ihre eigenen Threads können Sie jederzeit anzeigen oder killen, aber Sie
brauchen die @strong{process}-Berechtigung, um Threads anzuzeigen oder zu
killen, die von anderen Benutzern initiiert wurden. @xref{KILL}.

Es ist generell eine gute Idee, Berechtigungen nur den Nutzern zu gewähren,
die diese tatsächlich brauchen, aber speziell bei folgenden Berechtigungen
sollten Sie besondere Vorsicht walten lassen:

@itemize @bullet
@item
Die @strong{grant}-Berechtigung erlaubt Benutzern, Ihre Berechtigungen an
andere Benutzer zu übertragen. Zwei Benutzer mit unterschiedlichen
Berechtigungen und mit der @strong{grant}-Berechtigung sind in der Lage,
Ihre Berechtigungen zu kombinieren.

@item
Die @strong{alter}-Berechtigung kann benutzt werden, um das
Berechtigungssystem zu unterlaufen, indem Tabellen umbenannt werden.

@item
Die @strong{file}-Berechtigung kann missbraucht werden, um jede öffentlich
lesbare Datei auf dem Server in eine Datenbanktabelle einzulesen, auf deren
Inhalte dann mit @code{SELECT} zugegriffen werden kann. Das beinhaltet die
Inhalte aller Datenbanken, die vom Server gehostet werden!

@item
Die @strong{shutdown}-Berechtigung kann missbraucht werden, um andere
Benutzer komplett vom Server auszuschließen, indem der Server beendet
wird.

@item
Die @strong{process}-Berechtigung kann benutzt werden, um den Klartext von
momentan ablaufenden Anfragen einzusehen, inklusive Anfragen, die
Passwörter setzen oder ändern.

@item
Zugriffsrechte auf die @code{mysql}-Datenbank können benutzt werden, um
Passwörter zu ändern und auf sonstige Berechtigungsinformationen
zuzugreifen. (Passwörter werden verschlüsselt gespeichert, daher kann ein
böswilliger Benutzer sie nicht einfach lesen und anschließend die
Klartext-Passwörter kennen.) Wenn man auf die
@code{mysql.user}-Passwort-Spalte zugreifen kann, kann man das nutzen, um
sich als beliebiger Benutzer am MySQL-Server anzumelden. (Mit ausreichenden
Rechten kann derselbe Benutzer dann Passwörter durch eigene ersetzen.)
@end itemize

Es gibt einige Dinge, die Sie mit dem MySQL-Berechtigungssystem nicht tun
können:

@itemize @bullet
@item
Sie können nicht ausdrücklich festlegen, dass ein bestimmter Benutzer
keinen Zugriff haben soll. Das heißt, Sie können nicht explizit mit einem
bestimmten Benutzer vergleichen und dann die Verbindung ablehnen.

@item
Sie können nicht festlegen, dass ein Benutzer das Recht hat, Tabellen in
einer Datenbank zu erzeugen oder zu löschen, aber nicht die Datenbank
selbst zu erzeugen oder zu löschen.
@end itemize


@node Connecting, Connection access, Privileges provided, Privilege system
@c German node Verbinden
@subsection Verbinden mit dem MySQL-Server

@cindex Verbinden, mit dem MySQL-Server
@cindex Vorgabemäßiger Hostname
@cindex Hostname, Vorgabe
@cindex Server, verbinden

MySQL-Client-Programme erfordern im Allgemeinen, dass Sie
Verbindungsparameter festlegen, wenn Sie sich mit einem MySQL-Server
verbinden wollen: Der Host, mit dem Sie sich verbinden wollen, Ihr
Benutzername und Ihr Passwort. Beispielsweise kann der @code{mysql}-Client
wie folgt gestartet werden (optionale Argumente sind in @samp{[} und
@samp{]} eingeschlossen):

@example
shell> mysql [-h hostname] [-u benutzername] [-pihr_passwort]
@end example

Alternative Formen der @code{-h}-, @code{-u}- und @code{-p}-Optionen sind
@code{--host=hostname}, @code{--user=benutzername} und
@code{--password=ihr_passwort}. Beachten Sie, dass zwischen @code{-p} oder
@code{--password=} und dem folgenden Passwort @emph{kein Leerzeichen}
steht!

@strong{ACHTUNG:} Ein Passwort auf der Kommandozeile anzugeben ist nicht
sicher! Jeder Benutzer auf Ihrem System kann dann Ihr Passwort
herausfinden, indem er einen Befehl wie @code{ps auxww} eingibt.
@xref{Option files}.

@code{mysql} benutzt Vorgabewerte für Verbindungsparameter, die auf der
Kommandozeile nicht angegeben sind:

@itemize @bullet
@item
Der vorgabemäßige Hostname ist @code{localhost}.

@item
Der vorgabemäßige Benutzername ist Ihr Unix-Loginname.

@item
Es wird kein Passwort übergeben, wenn @code{-p} fehlt.
@end itemize

Für einen Unix-Benutzer @code{joe} sind daher folgende Befehle
gleichbedeutend:

@example
shell> mysql -h localhost -u joe
shell> mysql -h localhost
shell> mysql -u joe
shell> mysql
@end example

Andere MySQL-Clients verhalten sich ähnlich.

Auf Unix-Systemen können Sie andere Vorgabewerte festlegen, die benutzt
werden, wenn Sie eine Verbindung aufmachen, so dass Sie diese nicht jedes
Mal auf der Kommandozeile eingeben müssen, wenn Sie ein Client-Programm
aufrufen. Das kann auf verschiedene Weise gemacht werden:

@itemize @bullet
@item
@tindex .my.cnf-Datei
Sie können Verbindungsparameter im @code{[client]}-Abschnitt der
@file{.my.cnf}-Konfigurationsdatei in Ihrem Heimatverzeichnis festlegen.
Der relevante Abschnitt der Datei sieht etwa wie folgt aus:

@example
[client]
host=hostname
user=benutzername
password=ihr_passwort
@end example

@xref{Option files}.

@item
@tindex @code{MYSQL_HOST}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_HOST}
@tindex @code{MYSQL_PWD}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_PWD}
@tindex @code{USER}-Umgebungsvariable
@tindex Umgebungsvariable, @code{USER}
Sie können Verbindungsparameter festlegen, indem Sie Umgebungsvariablen
benutzen. Der Host kann für @code{mysql} festgelegt werden, indem
@code{MYSQL_HOST} benutzt wird. Der MySQL-Benutzername kann mit @code{USER}
festgelegt werden (nur für Windows). Das Passwort kann mit @code{MYSQL_PWD}
festgelegt werden (aber das ist unsicher, siehe nächster Abschnitt).
@xref{Environment variables}.
@end itemize


@node Connection access, Request access, Connecting, Privilege system
@c German node Verbindungszugriff
@subsection Zugriffskontrolle, Phase 1: Verbindungsüberprüfung

@cindex Zugriffskontrolle
@cindex Kontrolle über den Zugriff
@cindex Verbindung, Überprüfung
@cindex Testen, Verbindung mit dem Server

Wenn Sie versuchen, sich mit einem MySQL-Server zu verbinden, akzeptiert
der Server die Verbindung oder weist sie zurück, abhängig von Ihrer
Identität und davon, ob Sie diese mit dem korrekten Passwort verifizieren
können. Falls nicht, lehnt der Server den Zugriff vollständig ab. Ansonsten
akzeptiert der Server die Verbindung, geht dann in Phase 2 und wartet auf
Anfragen.

Ihre Identität basiert auf zwei Informationsbestandteilen:

@itemize @bullet
@item
Dem Host, von dem Sie sich verbinden

@item
Ihrem MySQL-Benutzernamen
@end itemize

Die Identitätsüberprüfung wird anhand der drei Geltungsbereichs-Felder der
@code{user}-Tabelle, nämlich (@code{Host}, @code{User} und @code{Password})
durchgeführt. Der Server akzeptiert die Verbindung nur, wenn ein
@code{user}-Tabelleneintrag mit Ihrem Hostnamen und Benutzernamen
übereinstimmt und Sie das korrekte Passwort angeben können.

Werte in den Geltungsbereichs-Feldern der @code{user}-Tabelle können wie folgt
festgelegt werden:

@itemize @bullet
@item
Ein @code{Host}-Wert kann ein Hostname oder eine IP-Nummer sein, oder
@code{'localhost'}, was die lokale Maschine angibt.

@item
@cindex Platzhalter (Wildcards), in der @code{mysql.user}-Tabelle
Sie können die Platzhalterzeichen @samp{%} und @samp{_} im @code{Host}-Feld
benutzen.

@item
Ein @code{Host}-Wert @code{'%'} stimmt mit jedem Hostnamen überein.

@item
Ein leerer @code{Host}-Wert bedeutet, dass die Berechtigung zusammen mit
dem Eintrag in der @code{host}-Tabelle gilt, der mit dem angegebenen
Hostnamen übereinstimmt. Weitere Informationen hierzu finden Sie im
nächsten Kapitel.

@cindex Netmask-Notation, in der @code{mysql.user}-Tabelle
@item
Ab MySQL-Version 3.23 können @code{Host}-Werte als IP-Nummern festgelegt
werden, und Sie können eine Netmask festlegen, die angibt, wie viele
Adress-Bits für die Netzwerknummer benutzt werden. Beispiel:

@example
GRANT ALL PRIVILEGES on db.* to david@@'192.58.197.0/255.255.255.0';
@end example

Das erlaubt jedem, sich von einer IP zu verbinden, bei der folgendes gilt:

@example
benutzer_ip & netmask = host_ip.
@end example

Im obigen Beispiel können sich alle IP's im Intervall zwischen 192.58.197.0
bis 192.58.197.255 mit dem MySQL-Server verbinden.

@item
@cindex anonymer Benutzer
Platzhalterzeichen sind im @code{User}-Feld nicht erlaubt. Sie können aber
einen leeren Wert angeben, der mit jedem Namen übereinstimmt. Wenn der
Eintrag in der @code{user}-Tabelle, der mit einer hereinkommenden
Verbindung übereinstimmt, einen leeren Benutzernamen hat, wird angenommen,
dass der Benutzer der anonyme Benutzer ist (der Benutzer ohne Namen), und
nicht der Name, den der Client tatsächlich angegeben hat. Das bedeutet,
dass ein leerer Benutzername für alle weiteren Zugriffsüberprüfungen
während der laufenden Verbindung benutzt wird (also während Phase 2).

@item
Das @code{Password}-Feld kann leer sein. Das bedeutet nicht, dass jedes
Passwort übereinstimmt, sondern dass der Benutzer sich ohne Angabe eines
Passworts verbinden muss.
@end itemize

@findex PASSWORD()
Nicht-leere @code{Password}-Werte repräsentieren verschlüsselte Passwörter.
MySQL speichert Passwörter nicht im Klartext, so dass jeder sie sehen
könnte. Statt dessen wird das Passwort eines Benutzers, der sich zu
verbinden versucht, verschlüsselt (unter Benutzung der
@code{PASSWORD()}-Funktion). Das verschlüsselte Passwort wird dann benutzt,
wenn Client / Server prüfen, ob das Passwort korrekt ist (das geschieht,
ohne dass das verschlüsselte Passwort jemals über die Verbindung übertragen
wird). Beachten Sie, dass aus der Sicht von MySQL das verschlüsselte
Passwort das ECHTE Passwort ist, daher sollten Sie niemandem Zugriff darauf
geben! Insbesondere sollten Sie keinem normalen Benutzer Lesezugriff auf
die Tabellen der @code{mysql}-Datenbank geben!

Die unten stehenden Beispiele zeigen, wie unterschiedliche Kombinationen
von @code{Host}- und-@code{User}-Werten in den
@code{user}-Tabelleneinträgen auf hereinkommende Verbindungen zutreffen:

@multitable @columnfractions .25 .15 .60
@item @code{Host} @strong{Wert} @tab @code{User} @strong{Wert} @tab @strong{Verbindungen, die mit dem Eintrag übereinstimmen}
@item @code{'thomas.loc.gov'} @tab @code{'fred'} @tab @code{fred}, der sich von @code{thomas.loc.gov} aus verbindet
@item @code{'thomas.loc.gov'} @tab @code{''} @tab Jeder Benutzer, der sich von @code{thomas.loc.gov} aus verbindet
@item  @code{'%'} @tab @code{'fred'} @tab @code{fred}, der sich von jedem Host aus verbindet
@item @code{'%'} @tab  @code{''} @tab Jeder Benutzer, der sich von jedem Host aus verbindet
@item @code{'%.loc.gov'} @tab @code{'fred'} @tab @code{fred}, der sich von jedem beliebigen Host in der @code{loc.gov}-Domäne aus verbindet
@item @code{'x.y.%'} @tab @code{'fred'} @tab @code{fred}, der sich von @code{x.y.net}, @code{x.y.com}, @code{x.y.edu} usw. aus verbindet (wahrscheinlich eher unsinnig)
@item @code{'144.155.166.177'} @tab @code{'fred'} @tab @code{fred}, der sich vom Host mit der IP-Adresse @code{144.155.166.177} aus verbindet
@item @code{'144.155.166.%'} @tab @code{'fred'} @tab @code{fred}, der sich von jedem beliebigen Host im Class-C-Subnet @code{144.155.166} aus verbindet
@item @code{'144.155.166.0/255.255.255.0'} @tab @code{'fred'} @tab Dasselbe wie im vorherigen Beispiel
@end multitable

Weil Sie im @code{Host}-Feld IP-Platzhalterwerte verwenden können
(beispielsweise @code{'144.155.166.%'}, was mit jedem Host in einem Subnet
übereinstimmt), besteht die Möglichkeit, dass jemand diese Fähigkeit
ausbeutet, indem er einen Host zum Beispiel
@code{144.155.166.somewhere.com} nennt. Um solche Versuche zu vereiteln,
verbietet MySQL den Vergleich mit Hostnamen, die mit Ziffern und einem
Punkt übereinstimmen. Wenn Sie daher einen Host haben, der so wie
@code{1.2.foo.com} benannt ist, wird sein Name nie mit der
@code{Host}-Spalte der Berechtigungstabellen übereinstimmen. Nur eine
IP-Nummer kann mit dem IP-Platzhalterwert übereinstimmen.

Eine hereinkommende Verbindung kann mit mehr als einem Eintrag in der
@code{user}-Tabelle übereinstimmen. Beispielsweise würde eine Verbindung
von @code{thomas.loc.gov} aus durch @code{fred} mit mehreren der oben
genannten Einträge übereinstimmen. Wie entscheidet der Server, welcher der
Einträge benutzt werden soll, wenn mehrere zutreffen? Der Server löst
dieses Problem, indem er die @code{user}-Tabelle nach dem Einlesen beim
Start sortiert, und danach die Einträge in sortierter Form durchsieht, wenn
ein Benutzer versucht, sich zu verbinden. Der erste übereinstimmende
Eintrag ist der, der benutzt wird.

Das Sortieren der @code{user}-Tabelle funktioniert wie folgt. Nehmen Sie
an, dass die @code{user}-Tabelle so aussieht:

@example
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| %         | root     | ...
| %         | jeffrey  | ...
| localhost | root     | ...
| localhost |          | ...
+-----------+----------+-
@end example

Wenn der Server die Tabelle liest, ordnet er die Einträge mit den
spezifischsten Einträgen für die @code{Host}-Werte zuerst ein (@code{'%'}
in der @code{Host}-Spalte bedeutet ``jeder Host'' und ist am
unspezifischsten). Einträge mit denselben @code{Host}-Werten werden mit den
spezifischsten @code{User}-Werten zuerst geordnet (ein leerer
@code{User}-Wert bedeutet ``jeder Benutzer'' und ist am
unspezifischsten). Die daraus resultierende sortierte @code{user}-Tabelle
sieht wie folgt aus:

@example
+-----------+----------+-
| Host      | User     | ...
+-----------+----------+-
| localhost | root     | ...
| localhost |          | ...
| %         | jeffrey  | ...
| %         | root     | ...
+-----------+----------+-
@end example

@cindex Berechtigungstabellen, sortieren
@cindex sortieren, Berechtigungstabellen
@cindex @code{user}-Tabelle, sortieren
Beim Versuch einer Verbindung durchsucht der Server die sortierten Einträge
und benutzt die ersten übereinstimmenden. Bei einer Verbindung von
@code{localhost} aus durch @code{jeffrey} stimmen die Werte zuerst mit den
Einträgen von @code{'localhost'} in der @code{Host}-Spalte überein. Hiervon
stimmt der Eintrag mit dem leeren Benutzernamen sowohl mit dem verbindenden
Host als auch mit dem Benutzernamen überein. (@code{'%'/'jeffrey'} hätte
auch übereingestimmt, aber er ist nicht der erste Tabelleneintrag, der
gefunden wird.)

Hier ist ein weiteres Beispiel. Nehmen Sie an, die @code{user}-Tabelle
sieht wie folgt aus:

@example
+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| %              | jeffrey  | ...
| thomas.loc.gov |          | ...
+----------------+----------+-
@end example

Die sortierte Tabelle sieht wie folgt aus:

@example
+----------------+----------+-
| Host           | User     | ...
+----------------+----------+-
| thomas.loc.gov |          | ...
| %              | jeffrey  | ...
+----------------+----------+-
@end example

Eine Verbindung von @code{thomas.loc.gov} aus durch @code{jeffrey} stimmt
mit dem ersten Eintrag überein, wohingegen eine Verbindung von
@code{whitehouse.gov} aus durch @code{jeffrey} mit dem zweiten Eintrag
übereinstimmt.

Ein häufiges Missverständnis besteht darin zu denken, dass bei einem
angegebenen Benutzernamen alle Einträge, die explizit den Benutzer nennen,
zuerst benutzt werden, wenn der Server versucht, eine Übereinstimmung für
die Verbindung zu finden. Das stimmt schlicht nicht. Das vorherige Beispiel
stellt das dar, wobei eine Verbindung von @code{thomas.loc.gov} aus durch
@code{jeffrey} zuerst gerade nicht mit dem Eintrag übereinstimmt, der
@code{'jeffrey'} als @code{User}-Feldwert enthält, sondern mit dem Eintrag,
der keinen Benutzernamen enthält!

Wenn Sie Probleme haben, sich mit dem Server zu verbinden, geben Sie die
@code{user}-Tabelle aus und sortieren Sie sich von Hand, um zu sehen, wo
die erste Übereinstimmung stattfindet.


@node Request access, Access denied, Connection access, Privilege system
@c German node Anfragezugriff
@subsection Zugriffskontrolle, Phase 2: Anfrageüberprüfung

Wenn Sie erst einmal eine Verbindung hergestellt haben, geht der Server in
Phase 2. Bei jeder Anfrage, die über diese Verbindung hereinkommt, prüft
der Server, ob Sie ausreichende Berechtigungen haben, sie auszuführen,
wobei es auf die Operation ankommt, die Sie ausführen wollen. Hier kommen
die Berechtigungsfelder der Berechtigungstabellen ins Spiel. Diese
Berechtigungen können aus jeder der @code{user}-, @code{db}-,
@code{host}-, @code{tables_priv}- oder @code{columns_priv}-Tabellen
stammen. Die Berechtigungstabellen werden mit @code{GRANT}- und
@code{REVOKE}-Befehlen verändert. @xref{GRANT, , @code{GRANT}}. (Hilfreich
sind die Ausführungen unter @ref{Privileges}, wo die Felder aufgelistet
sind, die sich in jeder der Berechtigungstabellen finden.)

Die @code{user}-Tabelle gewährt Berechtigungen, die Ihnen auf globaler
Ebene zugeordnet sind und die unabhängig von der gerade aktuellen Datenbank
zutreffen. Wenn beispielsweise die @code{user}-Tabelle Ihnen die
@strong{delete}-Berechtigung gewährt, können Sie Zeilen aus jeder Datenbank
auf dem Server-Host löschen! Mit anderen Worten: Berechtigungen in der
@code{user}-Tabelle sind Superuser-Berechtigungen. Es ist klug,
Berechtigungen in der @code{user}-Tabelle nur Superusern wie Server- oder
Datenbankverwaltern zu gewähren. Bei anderen Benutzern sollten Sie
Berechtigungen in der @code{user}-Tabelle auf @code{'N'} gesetzt lassen und
Berechtigungen nur auf Datenbank-Ebene gewähren, indem Sie die @code{db}-
und @code{host}-Tabellen benutzen.

@cindex anonymer Benutzer
@cindex Platzhalter, in @code{mysql.db}-Tabelle
@cindex Platzhalter, in @code{mysql.host}-Tabelle
Die @code{db}- und @code{host}-Tabellen gewähren Datenbank-spezifische
Berechtigungen. Werte in den Geltungsbereichs-Feldern können wie folgt
festgelegt werden:

@itemize @bullet
@item
Die Platzhalterzeichen @samp{%} und @samp{_} können in den @code{Host}- und
@code{Db}-Feldern jeder Tabelle benutzt werden.

@item
Ein @code{'%'}-@code{Host}-Wert in der @code{db}-Tabelle bedeutet ``jeder
Host.'' Ein leerer @code{Host}-Wert in der @code{db}-Tabelle bedeutet
``sieh in der @code{host}-Tabelle wegen weiterer Informationen nach''.

@item
Ein @code{'%'}- oder leerer @code{Host}-Wert in der @code{host}-Tabelle
bedeutet ``jeder Host''.

@item
Ein @code{'%'}- oder leerer @code{Db}-Wert in einer der Tabellen bedeutet
``jede Datenbank''.

@item
Ein leerer @code{User}-Wert in einer der Tabellen entspricht dem anonymen
Benutzer.
@end itemize

@cindex Berechtigungstabellen, sortieren
@cindex sortieren, Berechtigungstabellen
@cindex @code{db}-Tabelle, sortieren
@cindex @code{host}-Tabelle, sortieren
Die @code{db}- und @code{host}-Tabellen werden eingelesen und sortiert,
wenn der Server hoch fährt (zur gleichen Zeit, wenn er die
@code{user}-Tabelle einliest). Die @code{db}-Tabelle wird nach den
Geltungsbereichs-Feldern @code{Host}, @code{Db} und @code{User} sortiert.
Die @code{host}-Tabelle wird nach den Geltungsbereichs-Feldern @code{Host}
und @code{Db} sortiert. Bei der @code{user}-Tabelle werden die
spezifischsten Werte zuerst und die unspezifischsten Werte zuletzt
einsortiert, und wenn der Server nach übereinstimmenden Einträgen sucht,
benutzt er die erste Übereinstimmung, die er findet.


@cindex Platzhalter, in @code{mysql.tables_priv}-Tabelle
@cindex Platzhalter, in @code{mysql.columns_priv}-Tabelle
Die @code{tables_priv}- und @code{columns_priv}-Tabellen gewähren Tabellen-
und Spalten-spezifische Berechtigungen. Werte in der
Geltungsbereichs-Feldern können wie folgt festgelegt werden:

@itemize @bullet
@item
Die Platzhalterzeichen @samp{%} und @samp{_} können im @code{Host}-Feld
beider Tabellen benutzt werden.

@item
Ein @code{'%'}- oder leerer @code{Host}-Wert in jeder der beiden Tabellen bedeutet ``jeder Host.''

@item
Die @code{Db}-, @code{Table_name}- und @code{Column_name}-Felder dürfen in
beiden Tabellen keine Platzhalter enthalten oder leer sein.
@end itemize

Die @code{tables_priv}- und @code{columns_priv}-Tabellen werden nach den
@code{Host}-, @code{Db}- und @code{User}-Feldern sortiert. Das geschieht
ähnlich wie das Sortieren der @code{db}-Tabelle, wenngleich das Sortieren
einfacher ist, weil nur das @code{Host}-Feld Platzhalter enthalten darf.

Der Prozess der Anfragenüberprüfung ist weiter unten beschrieben. (Wenn Sie
mit dem Quelltext für die Zugangsüberprüfung vertraut sind, werden Sie
feststellen, dass die Beschreibung hier leicht vom im Code verwendeten
Algorithmus abweicht. Die Beschreibung stellt dar, was der Code tatsächlich
tut; sie weicht nur deshalb ab, um die Erklärung zu erleichtern.)

Bei Verwaltungsanfragen (@strong{shutdown}, @strong{reload} usw.) prüft der
Server nur den @code{user}-Tabelleneintrag, weil das die einzige Tabelle
ist, die Verwaltungsberechtigungen festlegt. Zugriff wird gewährt, wenn der
Eintrag die verlangte Operation erlaubt, ansonsten wird er verweigert. Wenn
Sie zum Beispiel @code{mysqladmin shutdown} ausführen wollen, aber Ihr
@code{user}-Tabelleneintrag Ihnen nicht die @strong{shutdown}-Berechtigung
gewährt, wird der Zugriff verweigert, ohne dass die @code{db}- oder
@code{host}-Tabellen geprüft werden. (Sie enthalten keine
@code{Shutdown_priv}-Spalte, daher gibt es keinen Grund, sie zur Prüfung
heranzuziehen.)

Bei Datenbank-bezogenen Anfragen (@strong{insert}, @strong{update} usw.)
prüft der Server zuerst die globalen (superuser-) Berechtigungen, indem er
im @code{user}-Tabelleneintrag nachsieht. Wenn der Eintrag die verlangte
Operation erlaubt, wird der Zugriff gewährt. Wenn die globalen
Berechtigungen in der @code{user}-Tabelle unzureichend sind, stellt der
Server die Datenbank-spezifischen Berechtigungen des Benutzers fest, indem
er die @code{db}- und @code{host}-Tabellen prüft:

@enumerate
@item
Der Server sieht in der @code{db}-Tabelle nach einer Übereinstimmung in den
@code{Host}-, @code{Db}- und @code{User}-Feldern nach. In den @code{Host}-
und @code{User}-Feldern wird nach Übereinstimmung mit dem Hostnamen
gesucht, von dem aus sich der Benutzer verbindet, und nach Übereinstimmung
mit dem MySQL-Benutzernamen. Im @code{Db}-Feld wird nach Übereinstimmung
mit der Datenbank gesucht, mit der sich der Benutzer verbinden will. Wenn
es keinen Eintrag für @code{Host} und @code{User} gibt, wird der Zugriff
verweigert.

@item
Wenn es keinen übereinstimmenden @code{db}-Tabelleneintrag gibt und das
@code{Host}-Feld nicht leer ist, bestimmt dieser Eintrag die
Datenbank-spezifischen Berechtigungen des Benutzers.

@item
Wenn das @code{Host}-Feld des übereinstimmenden @code{db}-Tabelleneintrags
leer ist, bedeutet das, dass die @code{host}-Tabelle festlegt, welchen
Hosts Zugriff auf die Datenbank erlaubt werden soll. In diesem Fall schlägt
der Server weiter in der @code{host}-Tabelle nach, um eine Übereinstimmung
in den @code{Host}- und @code{Db}-Feldern zu finden. Wenn kein
@code{host}-Tabelleneintrag passt, wird der Zugriff verweigert. Bei einer
Übereinstimmung werden die Datenbank-spezifischen Berechtigungen des
Benutzers als Schnittmenge (@emph{nicht} Vereinigungsmenge!) der
Berechtigungen in den @code{db}- und @code{host}-Tabelleneinträgen
berechnet, was die Berechtigungen ergibt, die in beiden Einträgen
@code{'Y'} sind. (Auf diese Weise können Sie allgemeine Berechtigungen in
den @code{db}-Tabelleneinträgen vergeben und diese dann fallweise von Host
zu Host beschränken, indem Sie die @code{host}-Tabelleneinträge benutzen.)
@end enumerate

Nachdem die Datenbank-spezifischen Berechtigungen festgestellt wurden, die
durch die @code{db}- und @code{host}-Tabelleneinträge gewährt werden, fügt
der Server diese zu den globalen Berechtigungen in der @code{user}-Tabelle
hinzu. Wenn das Ergebnis die verlangte Operation erlaubt, wird der Zugriff
gewährt. Ansonsten prüft der Server die Tabellen- und
Spalten-Berechtigungen des Benutzers in den @code{tables_priv}- und
@code{columns_priv}-Tabellen und fügt diese zu den Benutzerberechtigungen
hinzu. Aus dem Ergebnis ergibt sich, ob der Zugriff erlaubt oder verweigert
wird.

Als Boole'scher Term ausgedrückt kann die vorstehende Beschreibung der
Berechnung der Benutzerrechte wie folgt zusammengefasst werden:

@example
globale Berechtigungen
ODER (Datenbankberechtigungen UND Hostberechtigungen)
ODER Tabellenberechtigungen
ODER Spaltenberechtigungen
@end example

Vielleicht ist es nicht offensichtlich, warum der Server bei anfänglich als
unzureichend herausgefundenen globalen @code{user}-Eintragsberechtigungen
für die verlangte Operation diese Berechtigungen anschließend zu den
Datenbank-, Tabellen- und Spalten-spezifischen Berechtigungen hinzuzählt.
Der Grund liegt darin, dass eine Anfrage möglicherweise mehr als eine Sorte
von Berechtigungen erfordert. Wenn Sie beispielsweise ein @code{INSERT ...
SELECT}-Statement ausführen, brauchen Sie eventuell sowohl die
@strong{insert}- als auch die @strong{select}-Berechtigung. Ihre
Berechtigungen mögen so sein, dass der @code{user}-Tabelleneintrag eine
Berechtigung enthält und der @code{db}-Tabelleneintrag die andere. In
diesem Fall haben Sie die notwendigen Berechtigungen, die Anfrage
auszuführen, aber das Server kann das nicht aus nur einer der beiden
Tabellen heraus erkennen, sondern muss dafür die Einträge beider Tabellen
kombinieren.

@cindex @code{host}-Tabelle
@cindex Tabellen, @code{host}

Die @code{host}-Tabelle kann benutzt werden, um eine Liste sicherer Server
zu pflegen.

Bei TcX enthält die @code{host}-Tabelle eine Liste aller Maschine des
lokalen Netzwerks. Diesen werden alle Berechtigungen gewährt.

Sie können die @code{host}-Tabelle auch dazu benutzen, die Host
aufzuführen, die @emph{nicht} sicher sind. Nehmen Sie an, Sie haben eine
Maschine @code{oeffentlich.ihre.domaene}, die an einem öffentlichen Ort
ist, den Sie als nicht sicher erachten. Sie können allen Hosts in Ihrem
Netzwerk Zugriff gewähren ausser dieser Maschine, indem Sie die
@code{host}-Tabelleneinträge wie folgt benutzen:

@example
+--------------------------+----+-
| Host                     | Db | ...
+--------------------------+----+-
| oeffentlich.ihre.domane  | %  | ... (alle Berechtigungen auf 'N' gesetzt)
| %.ihre.domaene           | %  | ... (alle Berechtigungen auf 'Y' gesetzt)
+--------------------------+----+-
@end example

@cindex Berechtigungen, Änderungen
@cindex Änderungen der Berechtigungen
@cindex Tabellen, gewähren
@cindex Berechtigungstabellen

Natürlich sollten Sie Ihre Einträge in die Berechtigungstabellen immer
testen (indem Sie zum Beispiel @code{mysqlaccess} benutzen), um
sicherzustellen, dass Ihre Zugriffsberechtigungen tatsächlich so gesetzt
sind, wie Sie denken.


@node Access denied,  , Request access, Privilege system
@c German node Zugriff verweigert
@subsection Gründe für @code{Access denied}-Fehler

Wenn Sie beim Verbindungsversuch zu einem MySQL-Server @code{Access
denied}-Fehler bekommen, gibt Ihnen die folgende Liste ein paar Hinweise,
das Problem zu beheben:

@itemize @bullet
@item
Haben Sie nach der Installation von MySQL das
@code{mysql_install_db}-Skript laufen lassen, um die anfänglichen
Berechtigungstabelleninhalte zu konfigurieren? Wenn nicht, tun Sie das!
@xref{Default privileges}. Testen Sie die anfänglichen
Berechtigungen, indem Sie folgenden Befehl ausführen:

@example
shell> mysql -u root test
@end example

Der Server sollte die Verbindung ohne Fehlermeldung zulassen. Stellen Sie
auch sicher, dass Sie eine Datei @file{user.MYD} im
MySQL-Datenbankverzeichnis haben. Üblicherweise ist das
@file{PFAD/var/mysql/user.MYD}, wobei @code{PFAD} der Pfadname zum
MySQL-Installationsverzeichnis ist.

@item
Nach einer gerade durchgeführten Installation sollten Sie sich mit dem
Server verbinden und Ihre Benutzer und deren Zugriffsberechtigungen
einrichten:

@example
shell> mysql -u root mysql
@end example

Der Server sollte die Verbindung zulassen, weil der
MySQL-@code{root}-Benutzer anfänglich kein Passwort hat. Das ist ein
Sicherheitsrisiko, daher sollten Sie das @code{root}-Passwort einrichten,
während Sie Ihre anderen MySQL-Benutzer einrichten.

Wenn Sie versuchen, sich als @code{root} zu verbinden, und folgenden Fehler
erhalten:

@example
Access denied for user: '@@unknown' to database mysql
@end example

heißt das, dass Sie in der @code{user}-Tabelle keinen Eintrag
@code{'root'} im @code{User}-Spaltenwert haben und dass @code{mysqld} den
Hostnamen für Ihren Client nicht auflösen kann. In diesem Fall müssen Sie
den Server mit der @code{--skip-grant-tables}-Option neu starten und Ihrer
@file{/etc/hosts}- oder @file{\windows\hosts}-Datei einen Eintrag für Ihren
Host hinzufügen.

@item
Wenn Sie einen Fehler wie folgt erhalten:

@example
shell> mysqladmin -u root -pxxxx ver
Access denied for user: 'root@@localhost' (Using password: YES)
@end example

bedeutet das, dass Sie ein falsches Passwort benutzen. @xref{Passwords}.

Wenn Sie das Root-Passwort vergessen haben, können Sie @code{mysqld} mit
@code{--skip-grant-tables} neu starten, um das Passwort zu ändern. Diese
Option wird weiter hinten im Handbuch ausführlicher beschrieben.

Wenn Sie den obigen Fehler erhalten, obwohl Sie kein Passwort angegeben
haben, bedeutet das, dass in einer der @code{my.ini}-Dateien ein falsches
Passwort steht. @xref{Option files}. Sie können die Benutzung der
Optionsdateien mit der @code{--no-defaults}-Option wie folgt verhindern:

@example
shell> mysqladmin --no-defaults -u root ver
@end example

@item
@cindex @code{mysql_fix_privilege_tables}
Wenn Sie eine bestehende MySQL-Installation von einer Version vor 3.22.11
auf Version 3.22.11 oder später aktualisiert haben, haben Sie das
@code{mysql_fix_privilege_tables}-Skript ausgeführt? Falls nicht, tun Sie
das! Die Struktur der Berechtigungstabellen hat sich ab MySQL-Version
3.22.11 geändert, als das @code{GRANT}-Statement mit Funktion erfüllt
wurde.

@item
Falls es aussieht, als hätten sich Ihre Berechtigungen mitten in einer
Sitzung geändert, kann es sein, dass ein Superuser sie geändert hat. Das
Neuladen der Berechtigungstabellen betrifft neue
Client-Verbindungen, aber auch bestehende Verbindungen, wie in
@ref{Privilege changes} beschrieben.

@item
Wenn Sie es nicht schaffen, dass Ihr Passwort funktioniert, denken Sie
daran, dass Sie die @code{PASSWORD()}-Funktion benutzen müssen, wenn Sie
das Passwort mit den @code{INSERT}-, @code{UPDATE}- oder @code{SET
PASSWORD}-Statements setzen. Die @code{PASSWORD()}-Funktion wird nicht
benötigt, wenn Sie das Passwort mit dem @code{GRANT ... INDENTIFIED
BY}-Statement oder dem @code{mysqladmin password}-Befehl setzen.
@xref{Passwords}.

@item
@code{localhost} ist ein Synonym für Ihren lokalen Hostnamen und
gleichzeitig der vorgabemäßige Host, mit dem sich Clients versuchen zu
verbinden, wenn Sie nicht explizit einen Hostnamen angeben. Verbindungen zu
@code{localhost} funktionieren jedoch nicht, wenn Sie auf einem System
arbeiten, das MIT-pThreads benutzt (@code{localhost}-Verbindungen werden
über Unix-Sockets hergestellt, die von MIT-pThreads nicht unterstützt
werden). Um auf solchen Systemen Probleme zu vermeiden, sollten Sie die
@code{--host}-Option zu benutzen, um den Serverhost explizit anzugeben. Das
stellt eine TCP/IP-Verbindung zum @code{mysqld}-Server her. In diesem Fall
muss Ihr echter Hostname in den @code{user}-Tabelleneinträgen auf dem
Server-Host stehen. (Das gilt sogar dann, wenn Sie ein Client-Programm auf
demselben Host fahren, wo der Server läuft.)

@item
Wenn Sie beim Versuch, sich mit @code{mysql -u user_name db_name} mit einer
Datenbank zu verbinden, einen @code{Access denied}-Fehler erhalten, gibt es
eventuell ein Problem mit der @code{user}-Tabelle. Das können Sie
überprüfen, indem Sie @code{mysql -u root mysql} und folgendes
SQL-Statement absetzen:

@example
mysql> SELECT * FROM user;
@end example

Das Ergebnis sollte einen Eintrag enthalten, in dem die @code{Host}- und
@code{User}-Spalten mit dem Hostnamen Ihres Computers und Ihrem
MySQL-Benutzernamen übereinstimmen.

@item
Die @code{Access denied}-Fehlermeldung sagt Ihnen, als wer Sie sich
versuchen einzuloggen, den Host, von dem aus Sie versuchen, sich zu
verbinden, und ob Sie ein Passwort benutzen oder nicht. Normalerweise
sollten Sie in der @code{user}-Tabelle einen Eintrag haben, der exakt mit
Ihrem Hostnamen und Ihrem Benutzernamen übereinstimmt, die in der
Fehlermeldung ausgegeben wurden. Wenn Sie zum Beispiel eine Fehlermeldung
erhalten, die @code{Using password: NO} enthält, bedeutet das, dass Sie
versuchen sich einzuloggen, ohne ein Passwort anzugeben.

@item
Wenn Sie folgenden Fehler erhalten, wenn Sie sich von einem anderen Host
als dem, auf dem der MySQL-Server läuft, zu verbinden, gibt es keine Zeile
in der @code{user}-Tabelle, die mit Ihrem Host übereinstimmt:

@example
Host ... is not allowed to connect to this MySQL server
@end example

Das können Sie mit dem Kommandozeilentool @code{mysql} beheben (auf dem
Serverhost!) und eine Zeile zur @code{user}-, @code{db}- oder
@code{host}-Tabelle hinzufügen, die eine Benutzername-/Hostname-Kombination
enthält, von wo aus Sie sich verbinden wollen; danach führen Sie
@code{mysqladmin flush-privileges} aus. Wenn Sie nicht MySQL-Version 3.22
laufen lassen und die IP-Nummer oder den Hostnamen der Maschine nicht
kennen, von der aus Sie sich verbinden, sollten Sie einen Eintrag mit
@code{'%'} als @code{Host}-Spaltenwert in die @code{user}-Tabelle einfügen
und @code{mysqld} mit der @code{--log}-Option auf der Servermaschine neu
starten. Nach dem Verbinden von der Client-Maschine aus zeigt die
Information im MySQL-Log an, wie Sie sich wirklich verbunden haben.
(Ersetzen Sie danach @code{'%'} im @code{user}-Tabelleneintrag durch den
tatsächlichen Hostnamen, der im Log steht. Ansonsten erhalten Sie ein
System, das unsicher ist.)

Ein weiterer Grund für diesen Fehler unter Linux kann sein, dass Sie eine
Binärversion von MySQL benutzen, die mit einer anderen glibc-Version
kompiliert wurde als die, die Sie benutzen. In diesem Fall sollten Sie
entweder die glibc Ihres Betriebssystems aktualisieren oder die
Quellversion von MySQL herunter laden und sie selbst kompilieren. Ein
Quell-RPM läßt sich normalerweise sehr einfach kompilieren und
installieren, daher stellt dies kein großes Problem dar.

@item
Wenn Sie eine Fehlermeldung erhalten, in der der Hostname nicht angezeigt
wird oder eine IP-Nummer ist, obwohl Sie sich mit einem Hostnamen versuchen
zu verbinden:

@example
shell> mysqladmin -u root -pxxxx -h ein-hostname ver
Access denied für user: 'root@' (Using password: YES)
@end example

bedeutet das, dass MySQL einen Fehler beim Auflösen der IP zu einem
Hostnamen erhielt. In diesem Fall können Sie @code{mysqladmin flush-hosts}
ausführen, um den internen DNS-Cache zu flushen. @xref{DNS}.

Einige dauerhafte Lösungen sind:

@itemize @minus
@item
Versuchen Sie herauszufinden, was mit Ihrem DNS-Server nicht funktioniert,
und beheben Sie das Problem.

@item
Geben Sie in den MySQL-Berechtigungstabellen IP-Nummern statt Hostnamen an.

@item
Starten Sie @code{mysqld} mit @code{--skip-name-resolve}.

@item
Starten Sie @code{mysqld} mit @code{--skip-host-cache}.

@item
Verbinden Sie sich zu @code{localhost} wenn Sie Server und Client auf
derselben Maschine laufen lassen.

@item
Tragen Sie die Client-Maschinennamen in @code{/etc/hosts} ein.
@end itemize

@item
Wenn @code{mysql -u root test} funktioniert, aber @code{mysql -h
your_hostname -u root test} zu @code{Access denied} führt, haben Sie
eventuell nicht den korrekten Namen Ihres Hosts in der @code{user}-Tabelle.
Ein häufiges Problem hierbei ist, dass der @code{Host}-Wert im
@code{user}-Tabelleneintrag einen unqualifizierten Hostnamen festlegt, die
Namensauflösungsroutinen Ihres Systems aber einen voll qualifizierten
Domänennamen zurückgeben (oder umgekehrt). Wenn Sie zum Beispiel einen
Eintrag mit dem Host @code{'tcx'} in der @code{user}-Tabelle haben, Ihr DNS
MySQL aber mitteilt, dass Ihr Hostname @code{'tcx.subnet.se'} ist,
funktioniert der Eintrag nicht. Fügen Sie der @code{user}-Tabelle einen
Eintrag hinzu, der die IP-Nummer Ihres Hosts als @code{Host}-Spaltenwert
enthält. (Alternativ könnten Sie der @code{user}-Tabelle einen Eintrag mit
einem @code{Host}-Wert hinzufügen, der einen Platzhalter enthält, zum
Beispiel @code{'tcx.%'}. Allerdings ist die Benutzung von
Hostnamensendungen mit @samp{%} @emph{unsicher} und wird daher @emph{nicht}
empfohlen!)

@item
Wenn @code{mysql -u benutzername test} funktioniert, aber @code{mysql -u
benutzername andere_datenbank} nicht, haben Sie wahrscheinlich keinen
Eintrag für @code{andere_datenbank} in der @code{db}-Tabelle.

@item
Wenn @code{mysql -u benutzername datenbankname} funktioniert, wenn es auf
der Servermaschine ausgeführt wird, aber @code{mysql -u hostname -u
benutzername datenbankname} nicht, wenn es auf einer anderen Clientmaschine
ausgeführt wird, ist die Clientmaschine wahrscheinlich nicht in der
@code{user}-Tabelle oder der @code{db}-Tabelle aufgeführt.

@item
Wenn Sie gar nicht herausfinden können, warum Sie @code{Access denied}
erhalten, entfernen Sie aus der @code{user}-Tabelle alle Einträge, die
@code{Host}-Werte haben, die Platzhalter enthalten (Einträge, die @samp{%}
oder @samp{_} enthalten). Ein sehr häufiger Fehler besteht darin, einen
neuen Eintrag mit @code{Host}=@code{'%'} und
@code{User}=@code{'irgendein_benutzer'} in der Annahme hinzuzufügen, dass
einem das erlaubt, @code{localhost} anzugeben, um sich von derselben
Maschine aus zu verbinden. Der Grund, warum das nicht funktioniert, ist,
dass die vorgabemäßigen Berechtigungen einen Eintrag mit
@code{Host}=@code{'localhost'} und @code{User}=@code{''} enthalten. Weil
dieser Eintrag einen @code{Host}-Wert @code{'localhost'} hat, der
spezifischer ist als @code{'%'}, wird er vorrangig vor dem neuen Eintrag
benutzt, wenn man sich von @code{localhost} verbindet! Das korrekte
Vorgehen ist, einen zweiten Eintrag mit @code{Host}=@code{'localhost'} und
@code{User}=@code{'irgendein_benutzer'} hinzuzufügen, oder den Eintrag mit
@code{Host}=@code{'localhost'} und @code{User}=@code{''} zu entfernen.

@item
Wenn Sie den folgenden Fehler erhalten, gibt es eventuell Probleme mit der
@code{db}- oder der @code{host}-Tabelle:

@example
Access to database denied
@end example

Wenn der aus der @code{db}-Tabelle ausgewählte Eintrag einen leeren Wert in
der @code{Host}-Spalte hat, stellen Sie sicher, dass es einen oder mehrere
korrespondierende Einträge in der @code{host}-Tabelle gibt, die festlegen,
auf welche Hosts der @code{db}-Tabelleneintrag zutrifft.

Wenn Sie bei der Benutzung der SQL-Befehle @code{SELECT ... INTO OUTFILE}
oder @code{LOAD DATA INFILE} einen Fehler erhalten, enthält Ihr Eintrag in
der @code{user}-Tabelle wahrscheinlich keine angeschaltete
@strong{file}-Berechtigung.

@item
@cindex Konfigurationsdateien
@cindex Umgebungsvariablen
@tindex .my.cnf-Datei
Denken Sie daran, dass Client-Programme Verbindungsparameter benutzen, die
in Konfigurationsdateien oder Umgebungsvariablen festgelegt sind.
@xref{Environment variables}. Wenn ein Client anscheinend falsche
vorgabemäßige Verbindungsparameter sendet, wenn Sie diese nicht auf der
Kommandozeile angeben, überprüfen Sie Ihre Umgebung und die
@file{.my.cnf}-Datei in Ihrem Heimatverzeichnis. Überprüfen Sie
gegebenenfalls auch systemweite MySQL-Konfigurationsdateien, obwohl es sehr
viel unwahrscheinlicher ist, dass Client-Verbindungsparameter in diesen
festgelegt werden. @xref{Option files}. Wenn Sie beim Laufenlassen eines
Clients ohne irgend welche Optionen @code{Access denied} erhalten, stellen
Sie sicher, dass Sie kein altes Passwort in irgendeiner Optionsdatei
angegeben haben! @xref{Option files}.

@item
Wenn Sie in den Berechtigungstabellen direkte Änderungen vornehmen (indem
Sie ein @code{INSERT}- oder @code{UPDATE}-Statement benutzen) und Ihre
Änderungen anscheinend ignoriert werden, denken Sie daran, dass sie ein
@code{FLUSH PRIVILEGES}-Statement absetzen müssen oder einen
@code{mysqladmin flush-privileges}-Befehl ausführen, um den Server zu
veranlassen, die Berechtigungstabellen neu einzulesen. Ansonsten haben Ihre
Änderungen keine Auswirkung, bis der Server das nächste Mal gestartet wird.
Denken Sie auch daran, wenn Sie ein @code{root}-Passwort mit einem
@code{UPDATE}-Befehl festgelegt haben, dass Sie dieses solange nicht
angeben müssen, bis Sie die Berechtigungen flushen, weil der Server vorher
nicht weiß, dass Sie Ihr Passwort geändert haben!

@item
Wenn Sie Zugriffsprobleme mit einem Perl-, PHP-, Python- oder ODBC-Programm
haben, versuchen Sie, sich mit @code{mysql -u benutzername datenbankname}
oder @code{mysql -u benutzername -pihr_passwort datenbankname} zu
verbinden. Wenn es Ihnen gelingt, sich mittels des @code{mysql}-Clients zu
verbinden, gibt es ein Problem mit Ihrem Programm und nicht mit den
Zugriffsberechtigungen. (Beachten Sie, dass zwischen @code{-p} und dem
Passwort kein Leerzeichen steht; alternativ können Sie auch die
@code{--password=ihr_passwort}-Syntax benutzen, um Ihr Passwort anzugeben.
Wenn Sie die @code{-p}-Option allein benutzen, wird MySQL eine
Eingabeaufforderung für das Passwort anzeigen.)

@item
Zum Testen starten Sie den @code{mysqld}-Daemon mit der
@code{--skip-grant-tables}-Option. Anschließend können Sie die
MySQL-Berechtigungstabellen ändern und das @code{mysqlaccess}-Skript
benutzen, um zu sehen, ob Ihre Änderungen den gewünschten Effekt haben oder
nicht. Wenn Sie mit Ihren Änderungen zufrieden sind, führen Sie
@code{mysqladmin flush-privileges} aus, um @code{mysqld} mitzuteilen, die
neuen Berechtigungstabellen zu benutzen.  @strong{Beachten Sie:} Das
Neuladen der Berechtigungstabellen überschreibt die
@code{--skip-grant-tables}-Option. Das erlaubt Ihnen, den Server zu
veranlassen, die Berechtigungstabellen wieder zu benutzen, ohne ihn
herunter und dann wieder herauf fahren zu müssen.

@item
Wenn alles andere fehlschlägt, starten Sie den @code{mysqld}-Daemon mit
einer Debugging-Option (zum Beispiel @code{--debug=d,general,query}). Das
gibt Host- und Benutzerinformationen über Verbindungsversuche aus sowie
Informationen über jeden abgesetzten Befehl. @xref{Making trace files}.

@item
Wenn Sie irgend welche anderen Probleme mit den MySQL-Berechtigungstabellen
haben und meinen, das Problem der Mailing-Liste mitteilen zu müssen,
stellen Sie immer einen Auszug Ihrer MySQL-Berechtigungstabellen zur
Verfügung. Sie können einen Auszug der Tabellen mit dem @code{mysqldump
mysql}-Befehl erzeugen. Berichten Sie Ihr Problem - wie immer - unter
Benutzung des @code{mysqlbug}-Skripts. @xref{Bug reports}. In einigen
Fällen müssen Sie vielleicht @code{mysqld} mit @code{--skip-grant-tables}
neu starten, um @code{mysqldump} benutzen zu können.
@end itemize


@node User Account Management, Disaster Prevention, Privilege system, MySQL Database Administration
@c German node Benutzerkontenverwaltung
@section MySQL-Benutzerkonten-Verwaltung



@menu
* GRANT::                       
* User names::                  
* Privilege changes::           
* Default privileges::          
* Adding users::                
* User resources::              
* Passwords::                   
* Password security::           
@end menu

@node GRANT, User names, User Account Management, User Account Management
@c German node GRANT
@subsection @code{GRANT}- und @code{REVOKE}-Syntax

@findex GRANT
@findex REVOKE

@cindex Berechtigungen, gewähren
@cindex Berechtigungen, entziehen
@cindex global Berechtigungen
@cindex entziehen, Berechtigungen
@cindex gewähren, Berechtigungen

@example
GRANT berechtigung_art [(spalten_liste)] [, berechtigung_art [(spalten_liste)] ...]
    ON @{tabelle | * | *.* | datenbank.*@}
    TO benutzername [IDENTIFIED BY 'passwort']
        [, benutzername [IDENTIFIED BY 'passwort'] ...]
    [REQUIRE 
    	[@{SSL| X509@}] 
	[CIPHER cipher [AND]] 
	[ISSUER issuer [AND]] 
	[SUBJECT subject]]
    [WITH GRANT OPTION]

REVOKE berechtigung_art [(spalten_liste)] [, berechtigung_art [(spalten_liste)] ...]
    ON @{tabelle | * | *.* | datenbank.*@}
    FROM benutzername [, benutzername ...]
@end example

@code{GRANT} ist implementiert ab MySQL Version 3.22.11. Bei früheren
MySQL-Versionen bewirkt das @code{GRANT}-Statement nichts.

Die @code{GRANT}- und @code{REVOKE}-Befehle erlauben Systemverwaltern,
Benutzer anzulegen und MySQL-Benutzern Rechte auf vier Berechtigungsebenen
zu gewähren und zu entziehen:

@table @strong
@item Globale Ebene
Globale Berechtigungen betreffen alle Datenbanken auf einem gegebenen
Server. Diese Berechtigungen werden in der @code{mysql.user}-Tabelle
gespeichert.

@item Datenbank-Ebene
Datenbank-Berechtigungen betreffen alle Tabellen in einer gegebenen
Datenbank. Diese Berechtigungen werden in den @code{mysql.db}- und
@code{mysql.host}-Tabellen gespeichert.

@item Tabellen-Ebene
Tabellen-Berechtigungen betreffen alle Spalten in einer gegebenen Tabelle.
Diese Berechtigungen werden in der @code{mysql.tables_priv}-Tabelle
gespeichert.

@item Spalten-Ebene
Spalten-Berechtigungen betreffen einzelne Spalten in einer gegebenen
Tabelle. Diese Berechtigungen werden in der
@code{mysql.columns_priv}-Tabelle gespeichert.
@end table

Wenn Sie ein @code{GRANT} für einen Benutzer angeben, den es nicht gibt,
wird dieser Benutzer erzeugt. Beispiele, wie @code{GRANT} funktioniert,
finden Sie unter @ref{Adding users}.

Bei @code{GRANT} und @code{REVOKE}-Statements kann @code{berechtigung_art}
wie folgt angegeben werden:

@example
ALL PRIVILEGES      FILE                RELOAD
ALTER               INDEX               SELECT
CREATE              INSERT              SHUTDOWN
DELETE              PROCESS             UPDATE
DROP                REFERENCES          USAGE
@end example

@code{ALL} ist ein Synonym für @code{ALL PRIVILEGES}. @code{REFERENCES} ist
noch nicht implementiert. @code{USAGE} ist momentan ein Synonym für ``keine
Berechtigungen''. Es kann benutzt werden, um einen Benutzer zu erzeugen,
der keine Berechtigungen hat.

Um einem Benutzer die @strong{grant}-Berechtigung zu entziehen, benutzen
Sie einen @code{berechtigung_art}-Wert @code{GRANT OPTION}:

@example
REVOKE GRANT OPTION ON ... FROM ...;
@end example

Die einzigen @code{berechtigung_art}-Werte, die Sie für eine Tabelle
festlegen können, sind @code{SELECT}, @code{INSERT}, @code{UPDATE},
@code{DELETE}, @code{CREATE}, @code{DROP}, @code{GRANT}, @code{INDEX} und
@code{ALTER}.

Die einzigen @code{berechtigung_art}-Werte, die Sie für eine Spalte
festlegen können (im Falle, dass Sie eine @code{spalten_liste}-Klausel
benutzen), sind @code{SELECT}, @code{INSERT} und @code{UPDATE}.

Sie können globale Berechtigungen setzen, indem Sie die @code{ON
*.*}-Syntax benutzen. Datenbank-Berechtigungen setzen Sie mit der @code{ON
datenbank.*}-Syntax. Wenn Sie @code{ON *} setzen und eine aktuelle
Datenbank ausgewählt haben, setzen Sie die Berechtigungen für diese
Datenbank. (@strong{ACHTUNG:} Wenn Sie @code{ON *} festlegen und
@emph{keine} aktuelle Datenbank ausgewählt haben, betrifft das die globalen
Berechtigungen!)

Um die Rechtegewährung für Benutzer von uneindeutigen Hosts aus zu
ermöglichen, unterstützt MySQL den @code{benutzername}-Wert in der Form
@code{benutzer@@host}. Wenn Sie eine @code{user}-Zeichenkette festlegen
wollen, die Sonderzeichen enthält (wie @samp{-}), oder eine
@code{host}-Zeichenkette, die Sonderzeichen oder Platzhalterzeichen enthält
(wie @samp{%}), können Sie Benutzernamen oder Hostnamen in
Anführungszeichen setzen (beispielsweise @code{'test-benutzer'@@'test-hostname'}).

Sie können im Hostnamen Platzhalter angeben. @code{benutzer@@"%.loc.gov"}
zum Beispiel trifft auf @code{benutzer} für jeden Host in der Domäne
@code{loc.gov} zu. @code{benutzer@@"144.155.166.%"} trifft auf
@code{benutzer} für jeden Host im @code{144.155.166}-Class-C-Subnetz zu.

Die einfache Form @code{benutzer} ist ein Synonym für
@code{benutzer@@"%"}. @strong{ACHTUNG:} Wenn Sie anonymen Benutzern
erlauben, sich mit dem MySQL-Server zu verbinden (was vorgabemäßig der
Fall ist), sollten Sie auch alle lokalen Benutzer als
@code{benutzer@@localhost} hinzufügen, weil ansonsten der Eintrag für den
anonymen Benutzer für den lokalen Host in der @code{mysql.user}-Tabelle
benutzt wird, wenn der Benutzer versucht, sich von der lokalen Maschine in
den MySQL-Server einzuloggen! Anonyme Benutzer werden definiert, indem
Einträge mit @code{User=''} in die @code{mysql.user}-Tabelle eingefügt
werden. Das können Sie mit folgender Anfrage überprüfen:

@example
mysql> SELECT Host,User FROM mysql.user WHERE User='';
@end example

Momentan unterstützt @code{GRANT} nur Host-, Datenbank-, Tabellen- und
Spaltennamen mit maximal 60 Zeichen. Ein Benutzername kann bis zu 16
Zeichen lang sein.

Die Berechtigungen für eine Tabelle oder Spalte werden durch ein logisches
ODER der Berechtigungen auf jeder der vier Berechtigungsebenen zusammen
gesetzt. Wenn die @code{mysql.user}-Tabelle beispielsweise festlegt, dass
ein Benutzer eine globalen @strong{select}-Berechtigung hat, kann diese
nicht durch Einträge auf Datenbank-, Tabellen- oder Spaltenebene widerrufen
werden.

Die Berechtigungen für eine Spalte können wie folgt berechnet werden:

@example
Globale Berechtigungen
ODER (Datenbank-Berechtigungen UND Host-Berechtigungen)
ODER Tabellen-Berechtigungen
ODER Spalten-Berechtigungen
@end example

In den meisten Fällen können Sie einem Benutzer Rechte auf lediglich einer
der Berechtigungsebenen gewähren, wodurch das Leben nicht so kompliziert
ist wie oben dargestellt. Die Details der Prozedur zur Überprüfung der
Berechtigungen sind in @ref{Privilege system} dargestellt.

Wenn Sie Berechtigungen für eine Benutzer-/Hostname-Kombination gewähren,
die in der @code{mysql.user}-Tabelle nicht existiert, wird ein Eintrag
hinzugefügt und verbleibt dort, bis der mit einem @code{DELETE}-Befehl
gelöscht wird. Mit anderen Worten: @code{GRANT} kann eventuell
@code{user}-Tabelleneinträge erzeugen, aber @code{REVOKE} entfernt diese
nicht, sondern Sie müssen das explizit mit @code{DELETE} machen.

@cindex Passwörter, setzen
Ab MySQL-Version 3.22.12 wird, wenn ein neuer Benutzer erzeugt wird oder
wenn Sie globale Grant-Berechtigungen haben, das Passwort des Benutzers
durch die @code{IDENTIFIED BY}-Klausel festgelegt, wenn eine angegeben
wird. Wenn der Benutzer bereits ein Passwort hat, wird es durch das neue
ersetzt.

@strong{ACHTUNG:} Wenn Sie einen neuen Benutzer anlegen, aber keine
@code{IDENTIFIED BY}-Klausel angeben, hat der neue Benutzer kein Passwort.
Das ist unsicher.

Passwörter können auch mit dem @code{SET PASSWORD}-Befehl gesetzt werden.
@xref{SET OPTION, , @code{SET OPTION}}.

Wenn Sie Berechtigungen für eine Datenbank gewähren, wird ein Eintrag in
der @code{mysql.db}-Tabellen erzeugt, falls notwendig. Wenn alle
Berechtigungen für die Datenbank mit @code{REVOKE} widerrufen wurden, wird
dieser Eintrag gelöscht.

Wenn ein Benutzer überhaupt keine Berechtigungen auf eine Tabelle hat, wird
die Tabelle nicht angezeigt, wenn der Benutzer nach einer Liste von
Tabellen anfragt (zum Beispiel mit einem @code{SHOW TABLES}-Statement).

Die @code{mit GRANT OPTION}-Klausel gibt dem Benutzer die Möglichkeit,
anderen Benutzern jegliche der Berechtigungen zu vergeben, die der Benutzer
auf der angegebenen Berechtigungsebene hat. Sie sollten vorsichtig damit
sein, wem Sie die @strong{grant}-Berechtigung geben, denn zwei Benutzer mit
unterschiedlichen Berechtigungen können in der Lage sein, Ihre
Berechtigungen zu addieren!

Sie können einem Benutzer keine Berechtigung gewähren, die Sie selbst nicht
haben; die @strong{grant}-Berechtigung erlaubt Ihnen nur, die
Berechtigungen zu vergeben, die Sie selbst besitzen.

Wenn Sie einem Benutzer die @strong{grant}-Berechtigung auf einer
bestimmten Berechtigungsebene geben, denken Sie daran, dass der Benutzer
jegliche Berechtigungen, die der Benutzer schon besitzt (oder die ihm in
Zukunft gewährt werden!), auf dieser Ebene auch an andere Benutzer gewährt
werden können. Nehmen Sie an, Sie gewähren einem Benutzer die
@strong{insert}-Berechtigung auf eine Datenbank. Wenn Sie danach die
@strong{select}-Berechtigung auf die Datenbank mit @code{WITH GRANT OPTION}
gewähren, kann der Benutzer nicht nur die @strong{select}-Berechtigung
weiter geben, sondern auch @strong{insert}. Wenn Sie dem Benutzer danach
die @strong{update}-Berechtigung auf die Datenbank gewähren, kann der
Benutzer insgesamt @strong{insert}, @strong{select} und @strong{update}
weiter geben.

Sie sollten einem normalen Benutzer keine @strong{alter}-Berechtigung
gewähren. Wenn Sie das tun, kann der Benutzer versuchen, das
Berechtigungssystem zu unterlaufen, indem er Tabellen umbenennt!

Beachten Sie: Wenn Sie Tabellen- oder Spalten-Berechtigungen auch nur für
einen Benutzer gewähren, untersucht der Server Tabellen- und
Spalten-Berechtigungen für alle Benutzer. Dadurch wird MySQL etwas
langsamer.

Wenn @code{mysqld} startet, werden alle Berechtigungen in den Speicher
eingelesen. Datenbank-, Tabellen- und Spalten-Berechtigungen werden sofort
wirksam. Berechtigungen auf Benutzerebene werden wirksam, wenn sich der
Benutzer das nächste Mal verbindet. Änderungen in den
Berechtigungstabellen, die Sie mit @code{GRANT} oder @code{REVOKE}
durchführen, werden vom Server sofort bemerkt. Wenn Sie
Berechtigungstabellen manuell ändern (mit @code{INSERT}, @code{UPDATE}
usw.), müssen Sie ein @code{FLUSH PRIVILEGES}-Statement ausführen oder
@code{mysqladmin flush-privileges} laufen lassen, um den Server zu
veranlassen, die Berechtigungstabellen neu zu laden.
@xref{Privilege changes}.

@cindex ANSI SQL, Unterschiede zu
Die größten Unterschiede zwischen ANSI SQL und MySQL-Versionen von
@code{GRANT} sind:

@itemize @bullet
@item
In MySQL werden Berechtigungen für eine Benutzername-/Hostname-Kombination
vergeben und nicht nur für einen Benutzernamen.

@item
ANSI SQL hat keine globalen oder Datenbankebene-Berechtigungen und
unterstützt nicht alle Berechtigungsarten, die MySQL unterstützt. MySQL
unterstützt nicht die ANSI-SQL-@code{TRIGGER}-, @code{EXECUTE}- oder
@code{UNDER}-Berechtigungen.

@item
ANSI-SQL-Berechtigungen werden auf hierarchische Art strukturiert. Wenn Sie
einen Benutzer entfernen, werden alle Berechtigungen, die dieser Benutzer
gewährt hat, widerrufen. In MySQL werden die gewährten Berechtigungen nicht
automatisch widerrufen, sondern Sie müssen das selbst tun.

@item
Wenn Sie in MySQL das @code{INSERT}-Recht nur für Teile der Spalten einer
Tabelle haben, können Sie dennoch @code{INSERT}-Statements auf der Tabelle
ausführen. Die Spalten, für die Sie keine @code{INSERT}-Berechtigung haben,
werden auf ihre Vorgabewerte gesetzt. ANSI SQL erfordert, dass Sie die
@code{INSERT}-Berechtigung auf alle Spalten haben.

@item
Wenn Sie eine Tabelle in ANSI SQL löschen, werden alle Berechtigungen für
die Tabelle widerrufen. Wenn Sie eine Berechtigung in ANSI SQL widerrufen,
werden alle Berechtigungen, die auf dieser Berechtigung basierend gewährt
wurden, widerrufen. In MySQL können Berechtigungen nur explizit mit
@code{REVOKE}-Befehlen oder durch die Manipulation der
MySQL-Berechtigungstabellen widerrufen werden.
@end itemize

-----------
@cindex SSL- und X509-Grundlagen
MySQL unterstützt SSL-verschlüsselte Verbindungen. Um zu verstehen, wie
MySQL SSL benutzt, müssen wir einige Grundlagen von SSL und X509 erläutern.
Leute, die damit schon vertraut sind, können dieses Kapitel überspringen.

Vorgabemäßig benutzt MySQL unverschlüsselte Verbindungen zwischen Client
und Server. Das heißt, dass jeder auf dem Weg dazwischen lauschen und Ihre
Daten, die übertragen werden, mitlesen kann. Darüber hinaus könnten einige
Leute auch den Inhalt von Daten ändern, die zwischen Client und Server
ausgetauscht werden. Möglicherweise haben Sie auch wirklich geheime Daten
über öffentliche Netzwerke zu übertragen, und eine Öffentlichkeit solcher
Art ist unakzeptabel.

SSL ist ein Protokoll, das unterschiedliche Verschlüsselungsalgorithmen
benutzt, um sicherzustellen, dass Daten aus einem öffentlichen Netzwerk
vertraut werden kann. Es besitzt Mechanismen, um Veränderungen, Verlust
oder wiederholtes Abspielen (Replay) von Daten zu entdecken. SSL enthält
auch Algorithmen, um die Identität zu erkennen und zu überprüfen, indem der
X509-Standard benutzt wird.

@cindex Was ist Verschlüsselung
Mittels Verschlüsselung werden jegliche Arten von Daten unlesbar gemacht.
Darüber hinaus werden in der heutigen Praxis Verschlüsselungsalgorithmen
viele weitere Elemente hinzugefügt. Sie sollten vielen Arten bekannter
Angriffe widerstehen, wie dem Herumspielen mit der Reihenfolge
verschlüsselter Nachrichten oder dem doppelten Abspielen (Replay) von
Daten.

@cindex Was ist ein X509-Zertifikat?
X509 ist der Standard, der es ermöglicht, jemanden im Internet zu
identifizieren. Er wird meistens beim E-Commerce über das Internet benutzt.
Kurz gesagt sollte es ein Unternehmen namens "Zertifizierungsautorität"
geben, die jedem elektronische Zertifikate zuordnet, der diese braucht.
Zertifikate beruhen auf asymmetrischen Verschlüsselungsalgorithmen, die
zwei Verschlüsselungsschlüssel haben - öffentlichen und geheimen.
Zertifikatsbesitzer können ihre Identität jeder anderen Seite beweisen.
Zertifikate beinhalten den öffentlichen Schlüssel des Besitzers. Alle
Daten, die damit verschlüsselt werden, können nur vom Besitzer des geheimen
Schlüssels entschlüsselt werden.

@cindex Mögliche Fragen:
Frage: Warum benutzt MySQL nicht standardmäßig verschlüsselte Verbindungen?
Antwort: Weil es MySQL langsamer macht. Jede zusätzliche Funktionalität
erfordert, dass ein Computer zusätzliche Arbeit verrichtet, und das
Verschlüsseln von Daten ist eine CPU-intensive Operation, die leicht die
Zeit und Leistung übertreffen kann, die MySQL selbst verbraucht und
benötigt. MySQL ist vorgabemäßig auf Geschwindigkeit optimiert.
Frage: Ich brauche mehr Informationen über SSL / X509 / Verschlüsselung
usw.
Antwort: Benutzen Sie Ihre bevorzugte Internet-Suchmaschine und suchen Sie
nach den Schlüsselwörtern, die Sie interessieren.


@cindex SSL-bezogene Optionen

MySQL kann x509-Zertifikat-Attribute prüfen, zusätzlich zum meist benutzten
Benutzername-/Passwort-Schema. Alle gewöhnlich Optionen werden immer noch
benötigt (Benutzername, Passwörter, IP-Adressmaske,
Datenbank-/Tabellenname).

Es gibt verschiedene Möglichkeiten, Verbindungen zu begrenzen:

@itemize @bullet
@item
Ohne jegliche SSL-/X509-Optionen werden alle Arten verschlüsselter und
unverschlüsselter Verbindungen zugelassen, wenn Benutzername und Passwort
gültig sind.

@item
Die @code{REQUIRE SSL}-Option erzwingt SSL-verschlüsselte Verbindungen.
Beachten Sie, dass dieses Erfordernis übergangen werden kann, wenn es
irgend welche weiteren ACL-Datensätze gibt, die Verbindungen ohne SSL
zulassen.

Beispiel:
@example
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SSL
@end example


@item
* @code{REQUIRE X509} Wenn ein X509-Zertifikat erforderlich ist, bedeutet
das, dass der Client ein gültiges Zertifikat haben muss, aber wir kümmern
uns nicht um das genaue Zertifikat, den Herausgeber (Issuer) oder den
Betreff (Subject). Die einzige Einschränkung ist, dass es möglich sein
sollte, seine Unterschrift (Signature) mit einigen unserer CA-Zertifikate
zu überprüfen.

Beispiel:
@example
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE X509
@end example

@item
@code{REQUIRE ISSUER issuer} macht Verbindungen restriktiver: Jetzt muss
der Client ein gültiges X509-Zertifikat vorlegen, das von einem CA-Issuer
herausgegeben wurde. Die Benutzung von X509-Zertifikaten impliziert immer
Verschlüsselung, daher wird die Option "SSL" nicht mehr benötigt.

Beispiel:
@example
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finnland AB, CN=Tonu Samuel/Email=tonu@@mysql.com"
@end example

@item
@code{REQUIRE SUBJECT betreff} erfordert, dass der Client ein gültiges
X509-Zertifikat mit dem Betreff "betreff" darauf hat. Wenn der Client ein
gültiges Zertifikat hat, was aber einen anderen Betreff besitzt, wird die
Verbindung nicht zugelassen.

Beispiel:
@example
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com"
@end example

@item
@code{REQUIRE CIPHER cipher} wird benötigt um sicherzustellen, dass
Chiffrierungen und Schlüssellängen benutzt werden, die stark genug sind.
SSL selbst kann schwach sein, wenn alte Algorithmen mit kurzen
Verschlüsselungsschlüsseln benutzt werden. Wenn diese Option benutzt wird,
können wir exakte Chiffrierungen anfordern, bevor die Verbindung erlaubt
wird.

Beispiel:
@example
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" REQUIRE CIPHER "EDH-RSA-DES-CBC3-SHA"
@end example

Es ist erlaubt, die Optionen in Kombination wie folgt zu benutzen:
@example
GRANT ALL PRIVILEGES ON test.* TO root@@localhost IDENTIFIED BY "goodsecret" 
	REQUIRE SUBJECT "C=EE, ST=Some-State, L=Tallinn, O=MySQL demo client certificate, CN=Tonu Samuel/Email=tonu@@mysql.com" 
	AND ISSUER "C=FI, ST=Some-State, L=Helsinki, O=MySQL Finnland AB, CN=Tonu Samuel/Email=tonu@@mysql.com" 
	AND CIPHER "EDH-RSA-DES-CBC3-SHA"
@end example

Es ist aber nicht erlaubt, irgend eine der Optionen doppelt zu benutzen.
Nur unterschiedliche Optionen dürfen gemischt werden.
@end itemize
-----------

@node User names, Privilege changes, GRANT, User Account Management
@c German node Benutzernamen
@subsection MySQL-Benutzernamen und -Passwörter

@cindex Benutzernamen und Passwörter
@cindex Passwörter, für Benutzer

Es gibt mehrere Unterschiede in der Art, wie Benutzernamen und Passwörter
von MySQL benutzt werden, und der Art, wie sie von Unix oder Windows
benutzt werden:

@itemize @bullet
@item
Benutzernamen, wie sie von MySQL für Authentifizierungszwecke benutzt
werden, haben nicht zu tun mit Unix-Benutzernamen (Login-Namen) oder
Windows-Benutzernamen. Die meisten MySQL-Clients versuchen sich zwar
vorgabemäßig einzuloggen, indem sie den aktuellen Unix-Benutzernamen als
den MySQL-Benutzernamen verwenden, aber das geschieht nur aus Gründen der
Bequemlichkeit. Client-Programme lassen zu, dass ein anderer Name mit den
@code{-u}- oder @code{--user}-Optionen angegeben wird. Das bedeutet, dass
Sie eine Datenbank nicht auf irgend eine Weise sicher machen können, wenn
nicht alle MySQL-Benutzernamen Passwörter haben. Jeder kann versuchen, sich
mit dem Server zu verbinden, indem er irgend einen Namen angibt, und wird
damit Erfolg haben, wenn er einen Namen angibt, der kein Passwort hat.

@item
MySQL-Benutzernamen können bis zu 16 Zeichen lang sein; Unix-Benutzernamen
sind typischerweise auf 8 Zeichen begrenzt.

@item
MySQL-Passwörter haben nichts mit Unix-Passwörtern zu tun. Es gibt keine
notwendige Verbindungen zwischen dem Passwort, das Sie benutzen, um sich an
einer Unix-Maschine anzumelden, und dem Passwort, das Sie benutzen, um auf
eine Datenbank auf dieser Maschine zuzugreifen.

@item
@c German FIX unsplit @ref
MySQL verschlüsselt Passwörter mit einem anderen Algorithmus als dem, der
während des Unix-Login-Prozesses benutzt wird, siehe die Beschreibungen der
@code{PASSWORD()}- und @code{ENCRYPT()}-Funktionen in
@ref{Miscellaneous functions}.
Beachten Sie, dass trotz der Tatsache, dass das Passwort
'zerhackt' gespeichert wird, es ausreicht, Ihr 'zerhacktes' Passwort zu
kennen, um sich am MySQL-Server anmelden zu können!
@end itemize

MySQL-Benutzer und ihre Berechtigungen werden normalerweise mit dem
@code{GRANT}-Befehl erzeugt. @xref{GRANT}.

Wenn Sie sich an einem MySQL-Server mit einem Kommandozeilen-Client
anmelden, sollten Sie das Passwort mit @code{--password=ihr-passwort}
eingeben. @xref{Connecting}.

@example
mysql --user=monty --password=rate_mal datenbankname
@end example

Wenn Sie möchten, dass der Client eine Eingabeaufforderung für das Passwort
präsentiert, sollten Sie @code{--password} ohne Argument benutzen.

@example
mysql --user=monty --password datenbankname
@end example

Oder in der kurzen Form:

@example
mysql -u monty -p datenbankname
@end example

Beachten Sie, dass in den letzten Beispielen 'datenbankname' @strong{NICHT}
das Passwort ist.

Wenn Sie die @code{-p}-Option zur Eingabe des Passworts benutzen wollen,
tun Sie das wie folgt:

@example
mysql -u monty -prate_mal datenbankname
@end example

Auf einigen Systemen kürzt die Bibliothek, die MySQL benutzt, um die
Eingabeaufforderung für das Passwort auszugeben, das Passwort auf 8
Zeichen. Intern hat MySQL keine Beschränkung hinsichtlich der Länge des
Passworts.


@node Privilege changes, Default privileges, User names, User Account Management
@c German node Berechtigungsänderungen
@subsection Wann Berechtigungsänderungen wirksam werden

Wenn @code{mysqld} startet, werden alle Berechtigungstabelleninhalte in den
Arbeitsspeicher eingelesen und werden zu diesem Zeitpunkt wirksam.

Änderungen in den Berechtigungstabellen, die mit @code{GRANT},
@code{REVOKE} oder @code{SET PASSWORD} durchgeführt werden, werden
unmittelbar vom Server bemerkt.

Wenn Sie die Berechtigungstabellen manuell ändern (mit @code{INSERT},
@code{UPDATE} usw.), müssen Sie ein @code{FLUSH PRIVILEGES}-Statement
ausführen oder @code{mysqladmin flush-privileges} oder @code{mysqladmin
reload} laufen lassen, um den Server anzuweisen, die Berechtigungstabellen
neu einzulesen. Ansonsten haben Ihre Änderungen @emph{keine Auswirkung},
bis Sie den Server neu starten. Wenn Sie die Berechtigungstabellen manuell
ändern, aber vergessen, die Berechtigungen neu zu laden, werden Sie sich
wundern, warum trotz Ihrer Änderungen kein Unterschied zu bemerken ist!

Wenn der Server bemerkt, dass sich die Berechtigungstabellen geändert
haben, werden bestehende Client-Verbindungen wie folgt davon betroffen:

@itemize @bullet
@item
Tabellen- und Spalten-Berechtigungsänderungen werden bei der nächsten
Anfrage des Clients wirksam.

@item
Datenbank-Berechtigungsänderungen werden beim nächsten @code{USE
datenbank}-Befehl wirksam.
@end itemize

Globale Berechtigungsänderungen und Passwortänderungen werden beim nächsten
Mal wirksam, wenn sich der Client verbindet.


@node Default privileges, Adding users, Privilege changes, User Account Management
@c German node Vorgabemäßige Berechtigungen
@subsection Einrichtung der anfänglichen MySQL-Berechtigungen

@cindex Berechtigungen, vorgabemäßig
@cindex Vorgaben, Berechtigungen
@cindex Root-Passwort
@cindex Superuser
@cindex Benutzer, Root
@cindex anonymer Benutzer
@cindex Passwort, Root-Benutzer

Nach der Installation von MySQL konfigurieren Sie die anfänglichen
Zugriffsberechtigungen, indem Sie @code{scripts/mysql_install_db} laufen
lassen.
@xref{Quick install}.
Das @code{mysql_install_db}-Skript startet den @code{mysqld}-Server und
initialisiert dann die Berechtigungstabellen, so dass diese folgenden Satz
an Berechtigungen enthalten:

@itemize @bullet
@item
Der MySQL-@code{root}-Benutzer wird als Superuser angelegt, der alles tun
darf. Verbindungen müssen vom lokalen Host aus gemacht werden.

@strong{HINWEIS:}
Das anfängliche @code{root}-Passwort ist leer, daher kann sich jeder als
@code{root} @emph{ohne Passwort} verbinden und hat alle Berechtigungen.

@item
@cindex anonymer Benutzer
Ein anonymer Benutzer wird erzeugt, der mit Datenbanken, die den Namen
@code{'test'} haben oder mit @code{'test_'} anfangen, alles tun darf.
Verbindungen müssen vom lokalen Host aus gemacht werden. Das heißt, dass
sich jeder lokale Benutzer ohne Passwort verbinden kann und als anonymer
Benutzer behandelt wird.

@item
Andere Berechtigungen werden verweigert. Beispielsweise können normale
Benutzer nicht @code{mysqladmin shutdown} oder @code{mysqladmin
processlist} benutzen.
@end itemize

@strong{HINWEIS:} Die vorgabemäßigen Berechtigungen sind unter Windows
anders.
@xref{Windows running}.

Weil Ihre Installation anfangs weit offen ist, sollten Sie als eins der
ersten Dinge ein Passwort für den MySQL-@code{root}-Benutzer anlegen. Das
können Sie wie folgt tun (beachten Sie, dass das Passwort mit der
@code{PASSWORD()}-Funktion angegeben wird):

@example
shell> mysql -u root mysql
mysql> UPDATE user SET Password=PASSWORD('neues_passwort')
           WHERE user='root';
mysql> FLUSH PRIVILEGES;
@end example

Ab MySQL-Version 3.22 können Sie das @code{SET PASSWORD}-Statement
benutzen:

@example
shell> mysql -u root mysql
mysql> SET PASSWORD FOR root=PASSWORD('neues_passwort');
@end example

Eine weitere Möglichkeit, das Passwort zu setzen, besteht in der Benutzung
des @code{mysqladmin}-Befehls:

@example
shell> mysqladmin -u root password neues_passwort
@end example

Nur Benutzer mit Schreib-/Aktualisierungszugriff auf die
@code{mysql}-Datenbank können das Passwort für andere Benutzer ändern. Alle
normalen Benutzer (nicht anonyme Benutzer) können nur ihr eigenes Passwort
ändern, entweder mit einem der obigen Befehle oder mit @code{SET
PASSWORD=PASSWORD('neues_passwort')}.

Denken Sie daran, wenn Sie das Passwort in der @code{user}-Tabelle direkt
mit der ersten Methode ändern, dass Sie den Server anweisen müssen, die
Berechtigungstabellen neu einzulesen (mit @code{FLUSH PRIVILEGES}), weil
die Änderungen ansonsten nicht wahrgenommen werden.

Sobald das @code{root}-Passwort gesetzt wurde, müssen Sie in der Folge
immer das Passwort angeben, wenn Sie sich als @code{root} mit dem Server
verbinden.

Eventuell wollen Sie das @code{root}-Passwort leer lassen, damit Sie es für
die weitere Konfiguration oder für Tests nicht angeben müssen. Stellen Sie
jedoch sicher, dass Sie es setzen, bevor Sie Ihre Installation für irgend
welche Produktionsaufgaben benutzen.

Sehen Sie im @code{scripts/mysql_install_db}-Skript nach, wie es die
vorgabemäßigen Berechtigungen installiert. Sie können das als Grundlage
für das Hinzufügen weiterer Benutzer nehmen.

Wenn Sie wollen, dass die anfänglichen Berechtigungen anders sind als die
gerade beschriebenen, können Sie @code{mysql_install_db} abändern, bevor
Sie es benutzen.

@cindex Berechtigungstabellen, neu erzeugen
@cindex neu erzeugen, Berechtigungstabellen
Um die Berechtigungstabellen komplett neu zu erzeugen, entfernen Sie alle
@file{.frm}-, @file{.MYI}- und @file{.MYD}-Dateien im Verzeichnis, das die
@code{mysql}-Datenbank enthält. (Das ist das Verzeichnis namens
@file{mysql} unter dem Datenbank-Verzeichnis, was aufgelistet wird, wenn
Sie @code{mysqld --help} laufen lassen.) Lassen Sie dann das
@code{mysql_install_db}-Skript laufen, eventuell nachdem Sie es editiert
haben, um die Berechtigungen zu enthalten, die Sie haben wollen.

@strong{HINWEIS:} Bei MySQL-Versionen vor Version 3.22.10 sollten Sie die
@file{.frm}-Dateien NICHT löschen. Wenn Sie das versehentlich doch tun,
müssen Sie sie aus Ihrer MySQL-Distribution zurück kopieren, bevor Sie
@code{mysql_install_db} laufen lassen.


@node Adding users, User resources, Default privileges, User Account Management
@c German node Benutzer hinzufügen
@subsection Neue MySQL-Benutzer hinzufügen

@findex GRANT-Statement
@findex Statements, GRANT

@cindex Berechtigungen, hinzufügen
@cindex hinzufügen, neue Benutzerberechtigungen
@cindex Benutzerberechtigungen, hinzufügen

Sie können Benutzer auf zwei Arten hinzufügen: Indem Sie
@code{GRANT}-Statements verwenden oder indem Sie die
MySQL-Berechtigungstabellen direkt verändern. Die bevorzugte Methode ist,
@code{GRANT}-Statements zu benutzen, denn sie sind präziser und weniger
fehleranfällig. @xref{GRANT}.

Ausserdem gibt es eine Menge von Dritten beigesteuerte Programme wie
@code{phpmyadmin}, die benutzt werden können, um Benutzer zu erzeugen und
zu verwalten. @xref{Contrib}.

Die unten stehenden Beispiele zeigen, wie man den @code{mysql}-Client
benutzt, um neue Benutzer zu erzeugen. Die Beispiele setzen voraus, dass
Berechtigungen mit den Vorgabewerten eingerichtet wurden, die im vorherigen
Abschnitt beschrieben wurden. Um also Änderungen machen zu können, müssen
Sie sich von derselben Maschine aus verbinden, wo @code{mysqld} läuft, und
Sie müssen sich als MySQL-@code{root}-Benutzer verbinden, und der
@code{root}-Benutzer muss die @strong{insert}-Berechtigung für die
@code{mysql}-Datenbank und die @strong{reload}-Verwaltungsberechtigung
haben. Wenn Sie bereits das @code{root}-Benutzerpasswort geändert haben,
müssen Sie es für die unten stehenden @code{mysql}-Befehle eingeben.

Sie fügen neue Benutzer mit @code{GRANT}-Statements hinzu:

@example
shell> mysql --user=root mysql
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@@localhost
           IDENTIFIED BY 'ein_passwort' WITH GRANT OPTION;
mysql> GRANT ALL PRIVILEGES ON *.* TO monty@@"%"
           IDENTIFIED BY 'ein_passwort' WITH GRANT OPTION;
mysql> GRANT RELOAD,PROCESS ON *.* TO admin@@localhost;
mysql> GRANT USAGE ON *.* TO dummy@@localhost;
@end example

Diese @code{GRANT}-Statements richten drei neue Benutzer ein:

@table @code
@item monty
Einen echten Superuser, der sich von irgendwo her mit dem Server verbinden
kann, aber das Passwort @code{'ein_passwort'} dafür verwenden muss.
Beachten Sie, dass man @code{GRANT}-Statements sowohl für
@code{monty@@localhost} als auch für @code{monty@@"%"} verwenden muss. Wenn
man keinen Eintrag mit @code{localhost} hinzufügt, hat der Eintrag für den
anonymen Benutzer für @code{localhost} Vorrang, der durch
@code{mysql_install_db} angelegt wird, wenn man sich vom lokalen Host aus
verbindet, weil dieser einen spezifischeren @code{Host}-Feldwert hat und
daher früher in der @code{user}-Tabellen-Sortierreihenfolge auftaucht.

@item admin
Ein Benutzer, der sich ohne Passwort von @code{localhost} aus verbinden
kann und der die @strong{reload}- und @strong{process}-
Verwaltungsberechtigungen hat. Das erlaubt dem Benutzt, die
@code{mysqladmin reload}-, @code{mysqladmin refresh}- und @code{mysqladmin
flush-*}-Befehle sowie @code{mysqladmin processlist} auszuführen. Es werden
keine Datenbank-bezogenen Berechtigungen gewährt. (Diese können später
gewährt werden, indem zusätzliche @code{GRANT}-Statements ausgeführt
werden.)

@item dummy
Ein Benutzer, der sich ohne Passwort verbinden kann, aber nur vom lokalen
Host aus. Die globalen Berechtigungen sind alle auf @code{'N'} gesetzt -
diese @code{USAGE}-Berechtigung erlaubt Ihnen, einen Benutzer ohne
Berechtigungen anzulegen. Es wird angenommen, dass Sie später
Datenbank-spezifische Berechtigungen gewähren.
@end table

@findex INSERT-Statement, Grant-Berechtigungen
@findex Statements, INSERT
Sie können dieselben Benutzerzugriffsinformationen direkt mittels
@code{INSERT}-Statements eingeben und dann den Server anweisen, die
Berechtigungstabellen neu zu laden:

@example
shell> mysql --user=root mysql
mysql> INSERT INTO user VALUES('localhost','monty',PASSWORD('ein_passwort'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user VALUES('%','monty',PASSWORD('ein_passwort'),
                'Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO user SET Host='localhost',User='admin',
                 Reload_priv='Y', Process_priv='Y';
mysql> INSERT INTO user (Host,User,Password)
                        VALUES('localhost','dummy','');
mysql> FLUSH PRIVILEGES;
@end example

Abhängig von Ihrer MySQL-Version müssen Sie oben eventuell eine andere
Anzahl von @code{'Y'}-Werten eingeben (Versionen vor Version 3.22.11 hatten
weniger Berechtigungsspalten). Beim @code{admin}-Benutzer wird die besser
lesbare @code{INSERT}-Syntax benutzt, die ab Version 3.22.11 verfügbar ist.

Beachten Sie, dass Sie für die Einrichtung eines Superusers lediglich einen
@code{user}-Tabelleneintrag mit Berechtigungsfeldern einrichten müssen, die
auf @code{'Y'} gesetzt sind. Es sind keine @code{db}- oder
@code{host}-Tabelleneinträge nötig.

The Berechtigungsspalten in der @code{user}-Tabelle wurden im letzten
@code{INSERT}-Statement nicht explizit gesetzt (für den Benutzer
@code{dummy}), daher erhalten diese Spalten ihren Vorgabewert von
@code{'N'}. Das ist dasselbe, was @code{GRANT USAGE} macht.

Das folgende Beispiel fügt einen Benutzer @code{custom} hinzu, der sich von
@code{localhost}, @code{server.domain} und @code{whitehouse.gov} aus
verbinden kann. Er will auf die @code{bankkonto}-Datenbank nur von
@code{localhost} aus zugreifen, auf die @code{spesen}-Datenbank nur von
@code{whitehouse.gov} aus und auf die @code{kunde}-Datenbank von allen drei
Hosts aus. Er will von allen drei Hosts aus das Passwort @code{dumm}
benutzen.

Um die Berechtigungen dieses Benutzers mit @code{GRANT}-Statements
einzurichten, geben Sie folgende Befehle ein:

@example
shell> mysql --user=root mysql
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON bankkonto.*
           TO custom@@localhost
           IDENTIFIED BY 'dumm';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON spesen.*
           TO custom@@whitehouse.gov
           IDENTIFIED BY 'dumm';
mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP
           ON kunde.*
           TO custom@@'%'
           IDENTIFIED BY 'dumm';
@end example

Der Grund, warum wir Grant-Statements für den Benutzer 'custom' eingeben,
ist, dass wir dem Benutzer Zugriff auf MySQL sowohl von der lokalen
Maschine mit Unix-Sockets als auch von der entfernten Maschine
'whitehouse.gov' über TCP/IP geben wollen.

Um die Benutzerberechtigungen durch direkte Änderungen an den
Berechtigungstabellen einzugeben, geben Sie folgende Befehle ein (beachten
Sie das @code{FLUSH PRIVILEGES} am Ende):

@example
shell> mysql --user=root mysql
mysql> INSERT INTO user (Host,User,Password)
       VALUES('localhost','custom',PASSWORD('dumm'));
mysql> INSERT INTO user (Host,User,Password)
       VALUES('server.domain','custom',PASSWORD('dumm'));
mysql> INSERT INTO user (Host,User,Password)
       VALUES('whitehouse.gov','custom',PASSWORD('dumm'));
mysql> INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES
       ('localhost','bankkonto','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES
       ('whitehouse.gov','spesen','custom','Y','Y','Y','Y','Y','Y');
mysql> INSERT INTO db
       (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,
        Create_priv,Drop_priv)
       VALUES('%','kunde','custom','Y','Y','Y','Y','Y','Y');
mysql> FLUSH PRIVILEGES;
@end example

Die ersten drei @code{INSERT}-Statements fügen @code{user}-Tabelleneinträge
hinzu, die dem Benutzer @code{custom} erlauben, sich von den verschiedenen
Hosts aus mit dem gegebenen Passwort zu verbinden, gewähren ihm aber keine
Berechtigungen (alle Berechtigungen werden auf den Vorgabewert @code{'N'}
gesetzt). Die nächsten drei @code{INSERT}-Statements fügen
@code{db}-Tabelleneinträge hinzu, die @code{custom} Berechtigungen für die
@code{bankkonto}-, @code{spesen}- und @code{kunde}-Datenbanken gewähren,
aber nur, wenn auf sie von den korrekten Hosts aus zugegriffen wird. Wie
immer, wenn die Berechtigungstabellen direkt verändert werden, muss dem
Server gesagt werden, dass er sie neu laden muss (mit @code{FLUSH
PRIVILEGES}), damit die Berechtigungsänderungen wirksam werden.

Wenn Sie einem bestimmten Benutzer Zugriff von irgendeiner Maschine in
einer gegebenen Domäne geben wollen, können Sie ein @code{GRANT}-Statement
wie das folgende absetzen:

@example
mysql> GRANT ...
           ON *.*
           TO benutzername@@"%.domaene.de"
           IDENTIFIED BY 'passwort';
@end example

Um dasselbe durch direkte Änderung der Berechtigungstabellen einzugeben,
machen Sie folgendes:

@example
mysql> INSERT INTO user VALUES ('%.domaene.de', 'benutzername',
           PASSWORD('passwort'),...);
mysql> FLUSH PRIVILEGES;
@end example

Sie können auch @code{xmysqladmin}, @code{mysql_webadmin} und sogar
@code{xmysql} benutzen, um die Werte in den Berechtigungstabellen
einzufügen, zu ändern und zu aktualisieren. Sie finden diese Werkzeuge unter
@uref{http://www.mysql.com/downloads/contrib/,Contrib-Verzeichnis der
MySQL-Website}.

@node User resources, Passwords, Adding users, User Account Management
@c New section added by arjen 2002-05-17 to keep en/de in sync
@subsection Limiting user resources

@c FIX Original section text - to be translated.
@c FIX Also check manual.texi for other mentions of MAX_..._PER_HOUR

Starting from MySQL 4.0.2 one can limit certain resources per user.

So far, the only available method of limiting user usage of MySQL
server resources has been setting the @code{max_user_connections}
startup variable to a non-zero value. But this method is strictly
global and does not allow for management of individual users, which
could be of paricular interest to Internet Service Providers.

Therefore, management of three resources is introduced on the
individual user level:

@itemize @bullet
@item Number of all queries per hour:
All commands that could be run by a user.
@item Number of all updates per hour:
Any command that changes any table or database.
@item Number of connections made per hour:
New connections opened per hour.
@end itemize

A user in the aforementioned context is a single entry in the
@code{user} table, which is uniquely identified by its @code{user}
and @code{host} columns.

All users are by default not limited in using the above resources,
unless the limits are granted to them. These limits can be granted
@strong{only} via global @code{GRANT (*.*)}, using this syntax:

@example
GRANT ... WITH MAX_QUERIES_PER_HOUR = N1
               MAX_UPDATES_PER_HOUR = N2
               MAX_CONNECTIONS_PER_HOUR = N3;
@end example

One can specify any combination of the above resources.
N1, N2 and N3 are integers and stands for count / hour.

If user reaches any of the above limits withing one hour, his
connection will be terminated or refused and the appropriate error
message shall be issued.

Current usage values for a particular user can be flushed (set to zero)
by issuing a @code{GRANT} statement with any of the above clauses,
including a @code{GRANT} statement with the current values.

Also, current values for all users will be flushed if privileges are
reloaded (in the server or using @code{mysqladmin reload})
or if the @code{FLUSH USER_RESOURCES} command is issued.

The feature is enabled as soon as a single user is granted with any
of the limiting @code{GRANT} clauses.

As a prerequisite for enabling this feature, the @code{user} table in
the @code{mysql} database must contain the additional columns, as
defined in the table creation scripts @code{mysql_install_db} and
@code{mysql_install_db.sh} in @file{scripts} subdirectory.

@node Passwords, Password security, User resources, User Account Management
@c German node Passwörter
@subsection Passwörter einrichten

@findex PASSWORD()
@findex SET PASSWORD Statement

@cindex Passwörter, setzen
@cindex setzen, Passwörter

In den meisten Fällen sollten Sie @code{GRANT} benutzen, um Ihre Benutzer /
Passwörter einzurichten, daher trifft das folgende nur für fortgeschrittene
Benutzer zu. @xref{GRANT, , @code{GRANT}}.

Die Beispiele in den vorherigen Abschnitten erläutern ein wichtiges
Prinzip: Wenn Sie ein nicht leeres Passwort mit @code{INSERT}- oder
@code{UPDATE}-Statements setzen, müssen Sie die @code{PASSWORD()}-Funktion
benutzen, um es zu verschlüsseln. Das liegt daran, dass die
@code{user}-Tabelle Passwörter in verschlüsselter Form speichert, nicht als
Klartext. Wenn Sie diese Tatsache vergessen, ist es möglich, dass sie
Passwörter wie folgt setzen:

@example
shell> mysql -u root mysql
mysql> INSERT INTO user (Host,User,Password)
       VALUES('%','heinzholger','keks');
mysql> FLUSH PRIVILEGES;
@end example

Das Ergebnis ist, dass der Klartextwert @code{'keks'} als Passwort in
der @code{user}-Tabelle gespeichert ist. Wenn der Benutzer @code{heinzholger}
versucht, sich mittels dieses Passworts mit dem Server zu verbinden,
verschlüsselt der @code{mysql}-Client es mit @code{PASSWORD()}, erzeugt
damit einen Authentifikationsvektor, der auf dem @strong{verschlüsselten}
Passwort und einer Zufallszahl basiert, die er vom Server erhält, und
schickt das Ergebnis zum Server. Der Server benutzt den
@code{password}-Wert in der @code{user}-Tabelle (den @strong{nicht
verschlüsselten} Wert @code{'keks'}), um dieselben Berechnungen
durchzuführen, und vergleicht die Ergebnisse. Der Vergleich schlägt fehl
und der Server verweigert die Verbindung:

@example
shell> mysql -u heinzholger -pkeks test
Access denied
@end example

Passwörter müssen verschlüsselt sein, wenn sie in die @code{user}-Tabelle
eingefügt werden, daher hätte das @code{INSERT}-Statement also wie folgt
formuliert sein müssen:

@example
mysql> INSERT INTO user (Host,User,Password)
       VALUES('%','heinzholger',PASSWORD('keks'));
@end example

Sie müssen die @code{PASSWORD()}-Funktion auch benutzen, wenn Sie @code{SET
PASSWORD}-Statements gebrauchen:

@example
mysql> SET PASSWORD FOR heinzholger@@"%" = PASSWORD('keks');
@end example

Wenn Sie Passwörter mit dem @code{GRANT ... IDENTIFIED BY}-Statement oder
dem @code{mysqladmin password}-Befehl setzen, wird die
@code{PASSWORD()}-Funktion nicht benötigt. Beide sorgen dafür, dass das
Passwort verschlüsselt wird, daher würden Sie ein Passwort @code{'keks'}
wie folgt setzen:

@example
mysql> GRANT USAGE ON *.* TO heinzholger@@"%" IDENTIFIED BY 'keks';
@end example

oder

@example
shell> mysqladmin -u heinzholger password keks
@end example

@strong{NOTE:} @code{PASSWORD()} verschlüsselt Passwörter nicht auf
dieselbe Art, wie das bei Unix-Passwörtern der Fall ist. Wenn daher Ihr
Unix-Passwort und Ihr MySQL-Passwort identisch sind, sollten Sie daraus
nicht schließen, dass @code{PASSWORD()} denselben Verschlüsselungswert
ergibt wie der, der in der Unix-Passwortdatei gespeichert ist.
@xref{User names}.


@node Password security,  , Passwords, User Account Management
@c German node Passwort-Sicherheit
@subsection Wie Sie Ihre Passwörter sicher halten

Es ist nicht ratsam, Ihr Passwort so einzugeben, dass es von anderen
Benutzern entdeckt werden kann. Die verschiedenen Methoden, Passwörter
bei der Benutzung von Client-Programmen einzugeben, sind unten aufgeführt,
jeweils mit einer Einschätzung des Risikos der Methode:

@itemize @bullet
@item
Geben Sie einem normalen Benutzer nie Zugriff auf die
@code{mysql.user}-Tabelle. Wenn jemand das verschlüsselte Passwort für
einen Benutzer kennt, ermöglicht ihm das, sich als dieser Benutzer
einzuloggen. Die Passwörter sind nur 'zerhackt', so dass niemand das echte
Passwort sehen können sollte, das Sie benutzen (falls Sie ein ähnliches
Passwort für Ihre anderen Applikationen benutzen sollten).

@item
Sie können auf der Kommandozeile die @code{-pyour_pass}- oder
@code{--password=your_pass}-Option benutzen. Das ist bequem, aber unsicher,
weil Ihr Passwort für Systemzustandsprogramme (wie @code{ps}) sichtbar
wird, die möglicherweise von anderen Benutzer aufgerufen werden, um
Kommandozeilen anzuzeigen. (MySQL-Clients überschreiben typischerweise die
Kommandozeilenargumente während der Initialisierungssequenz mit Nullen,
dennoch gibt es einen kurzen Zeitraum, während dessen der Wert sichtbar
ist.)

@item
Sie können eine @code{-p}- oder @code{--password}-Option (ohne
@code{ihr_passwort}-Wert) benutzen. In diesem Fall erbittet das
Client-Programm das Passwort vom Terminal:
@findex -p-Option
@findex -password-Option

@example
shell> mysql -u benutzername -p
Enter password: ********
@end example

Die @samp{*}-Zeichen stehen für Ihr Passwort.

Es ist sicherer, Ihr Passwort auf diese Art einzugeben statt auf der
Kommandozeile, weil es für andere Benutzer nicht sichtbar wird. Diese
Methode ist jedoch nur für Programme geeignet, die interaktiv laufen. Wenn
Sie einen Client von einem Skript aus aufrufen wollen, das nicht interaktiv
läuft, gibt es keine Möglichkeit, das Passwort vom Terminal aus einzugeben.
Auf solchen Systemen kann es sogar vorkommen, dass die erste Zeile Ihres
Skripts gelesen und (fälschlicherweise) als Ihr Passwort interpretiert
wird!

@item
@tindex .my.cnf-Datei
Sie können Ihr Passwort in einer Konfigurationsdatei speichern.
Beispielsweise können Sie Ihr Passwort im @code{[client]}-Abschnitt der
@file{.my.cnf}-Datei in Ihrem Heimatverzeichnis aufführen:

@example
[client]
password=ihr_passwort
@end example

Wenn Sie Ihr Passwort in @file{.my.cnf} speichern, sollte die Datei nicht
für die Gruppe (group) lesbar oder schreibbar sein. Stellen Sie sicher,
dass der Zugriffsmodus der Datei @code{400} oder @code{600} ist.

@xref{Option files}.
@item
Sie können Ihr Passwort in der @code{MYSQL_PWD}-Umgebungsvariablen
speichern, aber diese Methode wird als extrem unsicher erachtet und sollte
nicht gewählt werden. Einige Versionen von @code{ps} beinhalten eine
Option, die Umgebung laufender Prozesse anzeigen zu lassen; Ihr Passwort
würde dann für alle im Klartext lesbar sein, wenn Sie @code{MYSQL_PWD}
setzen. Selbst auf Systemen ohne eine solche Version von @code{ps} ist es
nicht ratsam, anzunehmen, dass es keine andere Methode gibt,
Prozessumgebungen einzusehen. @xref{Environment variables}.
@end itemize

Alles in allem sind die sichersten Methoden, das Passwort entweder durch
Client-Programm entgegen nehmen zu lassen oder es in einer sauber
abgesicherten @file{.my.cnf}-Datei einzugeben.


@node Disaster Prevention, Database Administration, User Account Management, MySQL Database Administration
@c German node Katastrophenschutz und Wiederherstellung
@section Katastrophenschutz und Wiederherstellung



@menu
* Backup::                      
* BACKUP TABLE::                
* RESTORE TABLE::               
* CHECK TABLE::                 
* REPAIR TABLE::                
* Table maintenance::           
* Maintenance regimen::         
* Table-info::                  
@end menu

@node Backup, BACKUP TABLE, Disaster Prevention, Disaster Prevention
@c German node Datensicherung
@subsection Datenbank-Datensicherungen

@cindex Datenbanken, Datensicherungen
@cindex Datensicherungen

Weil MySQL-Tabellen als Dateien gespeichert werden, ist es leicht, eine
Datensicherung durchzuführen. Um eine konsistente Datensicherung zu
erhalten, machen Sie ein @code{LOCK TABLES} auf die relevanten Tabellen,
gefolgt von @code{FLUSH TABLES} für die Tabellen.
@xref{LOCK TABLES, , @code{LOCK TABLES}}.
@xref{FLUSH, , @code{FLUSH}}.
Sie brauchen lediglich eine Lesesperre (Read Lock); das erlaubt anderen
Threads, die Tabellen weiterhin abzufragen, während Sie eine Kopie der
Dateien im Datenbank-Verzeichnis machen. @code{FLUSH TABLE} wird benötigt,
um sicherzustellen, dass alle aktiven Indexseiten auf Platte zurück
geschrieben werden, bevor Sie die Datensicherung beginnen.

Wenn Sie eine Tabellensicherung auf SQL-Ebene machen wollen, können Sie
@code{SELECT INTO OUTFILE} oder @code{BACKUP TABLE} benutzen.
@xref{SELECT}. @xref{BACKUP TABLE}.

Eine weitere Möglichkeit, eine Datenbank zu sichern, stellt die Benutzung
des @code{mysqldump}-Programms oder des @code{mysqlhotcopy-Skript}s dar.
@xref{mysqldump, , @code{mysqldump}}. @xref{mysqlhotcopy, ,
@code{mysqlhotcopy}}.

@enumerate
@item
Machen Sie eine komplette Sicherung Ihrer Datenbanken:

@example
shell> mysqldump --tab=/pfad/zum/verzeichnis/ --opt --full

or

shell> mysqlhotcopy Datenbank /pfad/zum/verzeichnis/
@end example

Sie können auch einfach alle Tabellendateien (@file{*.frm}-, @file{*.MYD}-
und @file{*.MYI}-Dateien) kopieren, solange der Server nicht gerade etwas
aktualisiert. Das Skript @code{mysqlhotcopy} benutzt diese Methode.

@item
@cindex Log-Dateien, Namen
Halten Sie @code{mysqld} an, wenn er läuft, und starten Sie ihn mit der
@code{--log-update[=datei]}-Option. @xref{Update log}. Die
Update-Log-Datei(en) gibt Ihnen die Information, die Sie dafür benötigen,
um Änderungen an der Datenbank zu replizieren, die ab dem Zeitpunkt
durchgeführt wurden, als Sie @code{mysqldump} ausführten.
@end enumerate

Wenn Sie etwas wiederherstellen müssen, versuchen Sie zunächst, Ihre
Tabellen mit @code{REPAIR TABLE} oder @code{myisamchk -r} wieder
herzustellen. Das sollte in 99,9% aller Fälle funktionieren. Wenn
@code{myisamchk} fehlschlägt, probieren Sie folgende Prozedur (das
funktioniert nur, wenn Sie MySQL mit @code{--log-update} gestartet haben.
@xref{Update log}.):

@enumerate
@item
Stellen Sie die originale @code{mysqldump}-Datensicherung wieder her.
@item
Führen Sie folgenden Befehl aus, um die Aktualisierungen (Updates) im
Binär-Log noch einmal laufen zu lassen:

@example
shell> mysqlbinlog hostname-bin.[0-9]* | mysql
@end example

Wenn Sie das Update-Log benutzen, können Sie folgendes machen:

@example
shell> ls -1 -t -r hostname.[0-9]* | xargs cat | mysql
@end example
@end enumerate

@code{ls} wird benutzt, um alle Update-Log-Dateien in der richtigen
Reihenfolge zu erhalten.

Mit @code{SELECT * INTO OUTFILE 'datei' FROM tabelle} können Sie auch
selektive Datensicherungen herstellen und diese wieder herstellen mit
@code{LOAD DATA INFILE 'datei' REPLACE ...}. Um Duplikate zu vermeiden,
benötigen Sie einen Primärschlüssel (@code{PRIMARY KEY}) oder einen
eindeutigen Schlüssel (@code{UNIQUE}) in der Tabelle. Das Schlüsselwort
@code{REPLACE} führt dazu, dass alte Datensätze durch neue ersetzt werden,
wenn ein neuer Datensatz einen alten auf einem eindeutigen Schlüsselwert
duplizieren würde.

Wenn Sie bei der Datensicherung auf Ihrem System Performance-Probleme
bekommen, können Sie diese lösen, indem Sie Replikation einrichten und die
Datensicherungen auf dem Slave statt auf dem Master durchführen.
@xref{Replication Intro}.

Wenn Sie ein Veritas-Dateisystem benutzen, können Sie folgendes tun:

@enumerate
@item 
Führen Sie einen Client- (Perl ?) @code{FLUSH TABLES mit READ LOCK} aus.

@item
Forken Sie eine Shell oder führen Sie einen anderen Client aus @code{mount
vxfs snapshot}.

@item
Führen Sie im ersten Client @code{UNLOCK TABLES} aus.

@item
Kopieren Sie die Dateien von snapshot

@item
Unmounten Sie snapshot
@end enumerate


@node BACKUP TABLE, RESTORE TABLE, Backup, Disaster Prevention
@c German node BACKUP TABLE
@subsection @code{BACKUP TABLE}-Syntax

@findex BACKUP TABLE

@cindex Datensicherungen, Datenbank

@example
BACKUP TABLE tabelle[,tabelle...] TO '/pfad/zum/backup/verzeichnis'
@end example

Machen Sie eine Kopie aller Tabellendateien ins Datensicherungsverzeichnis,
was die Mindestanforderung für die Wiederherstellung darstellt. Momentan
funktioniert das nur bei @code{MyISAM}-Tabellen. Bei @code{MyISAM}-Tabellen
kopiert man @code{.frm}- (Definition) und @code{.MYD}- (Daten) Dateien. Die
Indexdatei kann aus diesen beiden aufgebaut werden.

@c German FIX changed @xref to @ref
Bevor Sie diesen Befehl ausführen, sehen Sie bitte unter
@ref{Backup} nach.

Während der Datensicherung gilt eine Lesesperre (Read Lock) für jede
Tabelle, eine nach der anderen, während sie gesichert werden. Wenn Sie
mehrere Tabellen als Schnappschuss sichern wollen, müssen Sie zuerst ein
@code{LOCK TABLES} ausführen, das eine Lesesperre für jede Tabelle in der
zu sichernden Gruppe enthält.

Der Befehl gibt eine Tabelle mit folgenden Spalten zurück:

@multitable @columnfractions .35 .65
@item @strong{Spalte} @tab @strong{Wert}
@item Table @tab Tabellenname
@item Op @tab Immer ``backup''
@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
@item Msg_text @tab Die Meldung.
@end multitable

Beachten Sie, dass @code{BACKUP TABLE} erst ab MySQL 3.23.25 verfügbar ist.


@node RESTORE TABLE, CHECK TABLE, BACKUP TABLE, Disaster Prevention
@c German node RESTORE TABLE
@subsection @code{RESTORE TABLE}-Syntax

@findex RESTORE TABLE

@example
RESTORE TABLE tabelle[,tabelle...] FROM '/pfad/zum/backup/verzeichnis'
@end example

Stellt die Tabelle(n) aus der Datensicherung her, die mit @code{BACKUP
TABLE} gesichert wurde(n). Bestehende Tabellen werden nicht überschrieben;
wenn Sie über bestehende Tabellen wiederherstellen wollen, erhalten Sie
eine Fehlermeldung. RESTORE benötigt länger als Datensicherung, weil der Index neu
aufgebaut werden muss. Je mehr Schlüssel Sie haben, desto länger dauert es.
Genau wie @code{BACKUP TABLE} funktioniert RESTORE momentan nur mit
@code{MyISAM}-Tabellen.


Der Befehl gibt eine Tabelle mit folgenden Spalten zurück:

@multitable @columnfractions .35 .65
@item @strong{Spalte} @tab @strong{Wert}
@item Table @tab Tabellenname
@item Op @tab Immer ``restore''
@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
@item Msg_text @tab Die Meldung.
@end multitable


@node CHECK TABLE, REPAIR TABLE, RESTORE TABLE, Disaster Prevention
@c German node CHECK TABLE
@subsection @code{CHECK TABLE}-Syntax

@findex CHECK TABLE

@example
CHECK TABLE tabelle[,tabelle...] [option [option...]]

option = QUICK | FAST | MEDIUM | EXTENDED | CHANGED
@end example

@code{CHECK TABLE} funktioniert nur bei @code{MyISAM}-Tabellen. Bei
@code{MyISAM}-Tabellen ist es dasselbe, wie @code{myisamchk -m tabelle}
über die Tabelle laufen zu lassen.

Wenn Sie keine Option angeben, wird @code{MEDIUM} benutzt.

Prüft die Tabelle(n) auf Fehler. Bei @code{MyISAM}-Tabellen werden die
Schlüssel-Statistiken aktualisiert. Der Befehl gibt eine Tabelle mit
folgenden Spalten zurück:

@multitable @columnfractions .35 .65
@item @strong{Spalte} @tab @strong{Wert}
@item Table    @tab Tabellenname
@item Op       @tab Immer ``check''.
@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
@item Msg_text @tab Die Meldung.
@end multitable

Beachten Sie, dass Sie viele Zeilen an Information für jede geprüfte
Tabelle erhalten. Die letzte Zeile enthält den @code{Msg_type status} und
sollte normalerweise @code{OK} sein. Wenn Sie nicht @code{OK} erhalten, oder @code{Not
checked}, sollten Sie im Normalfall eine Reparatur der Tabelle durchführen.
@xref{Table maintenance}. @code{Not checked} bedeutet, dass bei der Tabelle
der angegebene @code{TYPE} MySQL mitgeteilt hat, dass es keinerlei
Notwendigkeit gab, die Tabelle zu prüfen.

Die unterschiedlichen Prüfoptionen stehen für folgendes:

@multitable @columnfractions .20 .80
@item @strong{Option} @tab @strong{Bedeutung}
@item @code{QUICK} @tab Keine Zeilen nach falschen Verknüpfungen (Links) durchsehen (scannen).
@item @code{FAST}  @tab Nur Tabellen prüfen, die nicht ordnungsgemäß geschlossen wurden.
@item @code{CHANGED} @tab Nur Tabellen prüfen, die seit der letzten Prüfung geändert wurden oder die nicht ordnungsgemäß geschlossen wurden.
@item @code{MEDIUM} @tab Zeilen durchsehen (scannen), um zu bestätigen, dass gelöschte Verknüpfungen (Links) in Ordnung sind. Diese Option berechnet auch eine Schlüssel-Prüfsumme für die Zeilen und bestätigt diese mit einer berechneten Prüfsumme für die Schlüssel.
@item @code{EXTENDED} @tab Schlägt komplett alle Schlüssel für jede Zeile nach (Lookup). Hierdurch wird sichergestellt, dass die Tabelle 100% konsistent ist, aber das benötigt lange Zeit!
@end multitable

Bei @code{MyISAM}-Tabellen dynamischer Größe führt eine Prüfung immer
eine @code{MEDIUM}-Prüfung durch. Bei Zeilen statischer Länge wird das
Durchsehen (Scan) der Zeilen durch @code{QUICK} und @code{FAST}
übersprungen, weil solche Zeilen sehr selten beschädigt sind.

Sie können Prüfoptionen wie folgt kombinieren:

@example
CHECK TABLE test_tabelle FAST QUICK;
@end example

Das würde nur eine QUICK-Prüfung der Tabelle durchführen, wenn diese nicht
ordnungsgemäß geschlossen worden wäre.

@strong{HINWEIS:} In einigen Fällen kann @code{CHECK TABLE} zu einer
Änderung der Tabelle führen! Das geschieht, wenn die Tabelle als
'beschädigt' oder 'nicht ordnungsgemäß geschlossen' gekennzeichnet ist,
aber @code{CHECK TABLE} keine Probleme in der Tabelle gefunden hat. In
diesem Fall kennzeichnet @code{CHECK TABLE} die Tabelle als in Ordnung.

Wenn eine Tabelle beschädigt ist, liegt das Problem höchst wahrscheinlich
in den Indexen und nicht im Daten-Teil. Alle oben genannten Prüfoptionen
prüfen die Indexe gründlich und sollten daher die meisten Fehler finden.

Wenn Sie lediglich eine Tabelle prüfen wollen, von der Sie annehmen, dass
sie in Ordnung ist, sollten Sie keine Prüfoptionen oder die
@code{QUICK}-Option angeben. Letztere sollte benutzt werden, wenn Sie es
eilig haben und das sehr geringe Risiko auf sich nehmen können, dass
@code{QUICK} keinen Fehler in der Daten-Datei findet. (In den meisten Fällen
sollte MySQL bei normalem Gebrauch jeden Fehler in der Daten-Datei finden.
Wenn das geschieht, wird die Tabelle als 'beschädigt' gekennzeichnet, was
bedeutet, dass die Tabelle solange nicht benutzt werden kann, bis sie
repariert ist.)

@code{FAST} und @code{CHANGED} sind in erster Linie für die Benutzung durch
ein Skript vorgesehen (zum Beispiel für die Ausführung durch cron), wenn
Sie Ihre Tabellen von Zeit zu Zeit prüfen wollen. Für die meisten
Anwendungsfälle sollte man @code{FAST} vor @code{CHANGED} bevorzugen. (Der
einzige Fall, wo das nicht so ist, ist, wenn Sie vermuten, einen Bug im
@code{MyISAM}-Code gefunden zu haben.)

@code{EXTENDED} ist nur für den Fall vorgesehen, dass Sie eine normale
Prüfung haben durchlaufen lassen, aber immer noch seltsame Fehler von einer
Tabelle erhalten, wenn MySQL versucht, eine Zeile zu aktualisieren oder
eine Zeile über einen Schlüssel zu finden (das ist sehr unwahrscheinlich,
wenn eine normale Prüfung durchgelaufen ist!).

Es wurde berichtet, dass bei der Tabellenprüfung einige Dinge nicht
automatisch korrigiert werden können:

@itemize @bullet
@item
@code{Found row where the auto_increment column has the value 0}.

Das bedeutet, dass es in der Tabelle eine Zeile gibt, in der die
@code{auto_increment}-Index-Spalte den Wert 0 enthält. (Es ist möglich,
eine Zeile zu erzeugen, in der die auto_increment-Spalte 0 ist, indem man
die Spalte explizit mit einem @code{UPDATE}-Statement auf 0 setzt.)

Das ist für sich genommen kein Fehler, kann aber Probleme verursachen, wenn
Sie die Tabelle dumpen und dann wiederherstellen, oder ein @code{ALTER
TABLE} auf die Tabelle machen. In diesen Fällen ändert sich der Wert der
auto_increment-Spalte gemäß den Regeln für auto_increment-Spalten, was
Probleme wie doppelte Schlüsseleintragsfehler bringen könnte.

Um diese Warnmeldung loszuwerden, führen Sie einfach ein
@code{UPDATE}-Statement durch und setzen die Spalte auf irgend einen
anderen Wert als 0.
@end itemize


@node REPAIR TABLE, Table maintenance, CHECK TABLE, Disaster Prevention
@c German node REPAIR TABLE
@subsection @code{REPAIR TABLE}-Syntax

@findex REPAIR TABLE

@example
REPAIR TABLE tabelle[,tabelle...] [QUICK] [EXTENDED]
@end example

@code{REPAIR TABLE} funktioniert nur bei @code{MyISAM}-Tabellen und ist
dasselbe, wie @code{myisamchk -r tabelle} auf die Tabelle auszuführen.

Normalerweise sollten sie diesen Befehl nie ausführen müssen, aber wenn ein
Unglück passiert, ist es sehr wahrscheinlich, dass Sie alle Daten einer
MyISAM-Tabelle mit @code{REPAIR TABLE} retten können. Wenn Ihre Tabellen
häufig beschädigt werden, sollten Sie versuchen, den Grund hierfür
herauszufinden! @xref{Crashing}. @xref{MyISAM table problems}.

@code{REPAIR TABLE} repariert eine möglicherweise beschädigte Tabelle. Der
Befehl gibt eine Tabelle mit folgenden Spalten zurück:

@multitable @columnfractions .35 .65
@item @strong{Spalte} @tab @strong{Wert}
@item Table @tab Tabellenname
@item Op @tab Immer ``repair''
@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
@item Msg_text @tab Die Meldung.
@end multitable

Beachten Sie, dass Sie viele Zeilen an Informationen für jede reparierte
Tabelle erhalten. Die letzte Zeile enthält den @code{Msg_type status} und
sollte normalerweise @code{OK} sein. Wenn Sie nicht @code{OK} erhalten,
sollten Sie versuchen, die Tabelle mit @code{myisamchk -o} zu reparieren,
weil @code{REPAIR TABLE} noch nicht alle Optionen von @code{myisamchk}
enthält. In naher Zukunft werden wir das flexibler gestalten.

Wenn @code{QUICK} angegeben wird, versucht MySQL lediglich ein
@code{REPAIR} des Indexbaums.

Wenn Sie @code{EXTENDED} benutzen, erzeugt MySQL den Index Zeile für Zeile,
anstatt einen Index auf einmal durch Sortieren zu erzeugen. Das kann bei
Schlüsseln fester Länge besser sein, wenn Sie lange @code{char()}-Schlüssel
haben, die sich gut komprimieren lassen.


@node Table maintenance, Maintenance regimen, REPAIR TABLE, Disaster Prevention
@c German node Tabellenwartung
@subsection Benutzung von @code{myisamchk} für Tabellenwartung und Absturzreparatur

Ab MySQL-Version 3.23.13 können Sie MyISAM-Tabellen mit dem @code{CHECK
TABLE}-Befehl überprüfen. @xref{CHECK TABLE}. Mit dem @code{REPAIR
TABLE}-Befehl können Sie Tabellen reparieren. @xref{REPAIR TABLE}.

Um MyISAM-Tabellen (@code{.MYI} und @code{.MYD}) zu überprüfen und / oder
zu reparieren, sollten sie das @code{myisamchk}-Dienstprogramm benutzen. Um
ISAM-Tabellen (@code{.ISM} und @code{.ISD}) zu überprüfen und / oder zu
reparieren, sollten Sie das @code{isamchk}-Dienstprogramm benutzen.
@xref{Table types}.

Der folgende Text behandelt @code{myisamchk}, trifft aber voll umfänglich
auch auf das alte @code{isamchk} zu.

Sie können das @code{myisamchk}-Dienstprogramm benutzen, um Informationen über
Ihre Datenbanktabellen zu erhalten, sie zu prüfen und zu reparieren, oder
um sie zu optimieren. Die folgenden Abschnitte beschreiben, wie man
@code{myisamchk} aufruft (inklusive einer Beschreibung seiner Optionen),
wie man einen Wartungsplan für Tabellen erstellt und wie die
unterschiedlichen Funktionen von @code{myisamchk} benutzt werden.

In den meisten Fällen können Sie auch den Befehl @code{OPTIMIZE TABLES}
benutzen, um Tabellen zu optimieren und zu reparieren, aber dieser ist
nicht so schnell und (in Fall wirklich schwerer Fehler) nicht so
zuverlässig wie @code{myisamchk}. 
Auf der anderen Seite ist @code{OPTIMIZE TABLE} leichter zu benutzen, und
Sie brauchen sich nicht um das Flushen von Tabellen zu kümmern.
@xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.

Obwohl das Reparieren bei @code{myisamchk} recht sicher ist, ist es immer
eine gute Idee, eine Datensicherung zu machen, bevor eine Reparatur
durchgeführt wird (oder etwas Sonstiges, das viele Änderungen an einer
Tabelle durchführt).



@menu
* myisamchk syntax::            
* myisamchk general options::   
* myisamchk check options::     
* myisamchk repair options::    
* myisamchk other options::     
* myisamchk memory::            
* Crash recovery::              
* Check::                       
* Repair::                      
* Optimisation::                
@end menu

@node myisamchk syntax, myisamchk general options, Table maintenance, Table maintenance
@c German node myisamchk-Syntax
@subsubsection Aufrufsyntax von @code{myisamchk}

@code{myisamchk} wird wie folgt aufgerufen:

@example
shell> myisamchk [optionen] tabelle
@end example

@code{optionen} legt fest, was @code{myisamchk} tun soll. Die Optionen sind
unten beschrieben. (Sie erhalten eine Liste der Optionen, wenn Sie
@code{myisamchk --help} eingeben.) Ohne Optionen aufgerufen prüft
@code{myisamchk} einfach nur Ihre Tabelle. Um mehr Informationen zu
erhalten oder @code{myisamchk} anzuweisen, korrigierende Aktionen
durchzuführen, geben Sie Optionen wie unten und in den folgenden
Abschnitten beschrieben an.

@code{tabelle} ist die Datenbanktabelle, die Sie prüfen oder reparieren
wollen. Wenn Sie @code{myisamchk} anderswo als im Datenbank-Verzeichnis
ausführen, müssen Sie den Pfad zur Datei angeben, denn @code{myisamchk}
weiß nicht, wo Ihre Datenbank liegt. In der Tat kümmert sich
@code{myisamchk} nicht darum, ob die Dateien, die es bearbeiten soll, in
einem Datenbank-Verzeichnis liegen oder nicht; sie können diese Dateien
daher an eine andere Stelle kopieren und die Wiederherstellungsoperationen
dort durchführen.

Sie können in der @code{myisamchk}-Befehlszeile mehrere Tabellen angeben,
wenn Sie wollen. Sie können auch einen Namen als Indexdateinamen angeben
(mit dem Suffix @file{.MYI}), was Ihnen gestattet, alle Tabellen in einem
Verzeichnis anzugeben, indem Sie das Muster @file{*.MYI} benutzen. Wenn Sie
zum Beispiel in einem Datenbank-Verzeichnis sind, können Sie alle Tabellen
im Verzeichnis wie folgt prüfen:

@example
shell> myisamchk *.MYI
@end example

Wenn Sie nicht im Datenbank-Verzeichnis sind, können Sie alle dortigen
Tabellen prüfen, indem Sie den Pfad zum Verzeichnis angeben:

@example
shell> myisamchk /pfad/zum/datenbank_verzeichnis/*.MYI
@end example

Sie können sogar alle Tabellen in allen Datenbanken prüfen, indem Sie einen
Platzhalter im Pfad zum MySQL-Daten-Verzeichnis angeben:

@example
shell> myisamchk /pfad/zum/datadir/*/*.MYI
@end example

Um schnell alle Tabellen zu prüfen, wird folgender Befehl empfohlen:

@example
myisamchk --silent --fast /pfad/zum/datadir/*/*.MYI
isamchk --silent /pfad/zum/datadir/*/*.ISM
@end example

Wenn Sie alle Tabellen prüfen und alle Tabellen reparieren wollen, die
beschädigt sind, können Sie folgende Kommandozeile eingeben:

@example
myisamchk --silent --force --fast --update-state -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M /pfad/zum/datadir/*/*.MYI
isamchk --silent --force -O key_buffer=64M -O sort_buffer=64M -O read_buffer=1M -O write_buffer=1M /pfad/zum/datadir/*/*.ISM
@end example

Hierbei wird angenommen, dass Sie mehr als 64 MB Arbeitsspeicher frei
haben.

Wenn Sie einen Fehler wie den folgenden erhalten:

@example
myisamchk: warning: 1 clients is using oder hasn't closed the table properly
@end example

Bedeutet das, dass Sie versuchen, eine Tabelle zu überprüfen, die durch ein
anderes Programm aktualisiert wurde (wie dem @code{mysqld}-Server), das die
Datei noch nicht geschlossen hat oder das abgestürzt ist, ohne die Datei
ordnungsgemäß zu schließen.

Wenn @code{mysqld} läuft, müssen Sie ein Sync/Schließen aller Tabellen mit
@code{FLUSH TABLES} erzwingen und sicherstellen, dass niemand die Tabellen
benutzt, während Sie @code{myisamchk} laufen lassen. In MySQL-Version 3.23
ist die einfachste Möglichkeit, dieses Problem zu vermeiden, die Benutzung
von @code{CHECK TABLE} anstelle von @code{myisamchk}.



@node myisamchk general options, myisamchk check options, myisamchk syntax, Table maintenance
@c German node Allgemeine Optionen für myisamchk
@subsubsection Allgemeine Optionen für @code{myisamchk}

@cindex Optionen, @code{myisamchk}
@cindex @code{myisamchk}, Optionen

@code{myisamchk} unterstützt folgende Optionen:

@table @code
@item -# oder --debug=debug_optionen
Ausgabe eines Debug-Logs. Die Zeichenkette @code{debug_optionen} ist häufig
@code{'d:t:o,dateiname'}.
@item -? oder --help
Hilfetext ausgeben und beenden.
@item -O var=option, --set-variable var=option
Setzt den Wert einer Variablen. Mögliche Variablen und ihre Vorgabewerte
für myisamchk können mit @code{myisamchk --help} herausgefunden werden:
@multitable @columnfractions .3 .7
@item key_buffer_size @tab 523264
@item read_buffer_size @tab 262136
@item write_buffer_size @tab 262136
@item sort_buffer_size @tab 2097144
@item sort_key_blocks @tab 16
@item decode_bits @tab 9
@end multitable

@code{sort_buffer_size} wird benutzt, wenn Schlüssel repariert werden,
indem Schlüssel sortiert werden, was der Normalfall ist, wenn Sie
@code{--recover} benutzen.

@code{key_buffer_size} wird benutzt, wenn Sie die Tabelle mit
@code{--extended-check} prüfen oder wenn die Schlüssel repariert werden,
indem Schlüssel Zeile für Zeile in die Tabelle eingefügt werden (als wenn
normale Einfügeoperationen (Insert) durchgeführt werden). Eine Reparatur
mittels Key-Buffer (Schlüsselpuffer) wird in folgenden Fällen benutzt:

@itemize @bullet
@item
Wenn Sie @code{--safe-recover} benutzen.
@item
Wenn die temporären Dateien, die benötigt werden, um die Schlüssel zu
sortieren, mehr als zweimal so Groß werden würden, als wenn die
Schlüsseldatei direkt erzeugt würde. Das ist oft dann der Fall, wenn Sie
große @code{CHAR}-, @code{VARCHAR}- oder @code{TEXT}-Schlüssel haben, weil
das Sortieren die gesamten Schlüssel während des Sortierens speichern muss.
Wenn Sie viel temporären Platz haben und @code{myisamchk} zwingen können,
mittels Sortieren zu reparieren, können Sie die
@code{--sort-recover}-Option benutzen.
@end itemize

Die Reparatur durch den Key-Buffer (Schlüsselpuffer) nimmt weit weniger
Plattenplatz in Anspruch als wenn Sortieren benutzt wird, ist aber auch
viel langsamer.

Wenn Sie eine schnellere Reparatur wollen, setzen Sie die obigen Variablen
auf ungefähr 1/4 Ihres verfügbaren Arbeitsspeichers. Sie können beide
Variablen auf große Werte setzen, weil nur einer der oben aufgeführten
Puffer zur gleichen Zeit benutzt wird.

@item -s oder --silent
Schweigsamer Modus. Ausgaben erfolgen nur im Fehlerfall. Sie können
@code{-s} doppelt benutzen (@code{-ss}), um @code{myisamchk} sehr
schweigsam zu machen.
@item -v oder --verbose
Geschwätziger Modus. Es werden mehr Informationen ausgegeben. Dies kann
auch bei @code{-d} und @code{-e} benutzt werden. Benutzen Sie @code{-v}
mehrfach (@code{-vv}, @code{-vvv}), um noch ausführlichere Meldungen
auszugeben!
@item -V oder --version
Die aktuelle Version von @code{myisamchk} ausgeben und beenden.
@item -w or, --wait
Statt einen Fehler auszugeben, wenn die Tabelle gesperrt ist, warten, bis
die Tabelle entsperrt ist, bevor fortgefahren wird. Beachten Sie: Wenn Sie
@code{mysqld} auf der Tabelle mit @code{--skip-locking} laufen lassen, kann
die Tabelle nur mit einem weiteren @code{myisamchk}-Befehl gesperrt werden.
@end table


@node myisamchk check options, myisamchk repair options, myisamchk general options, Table maintenance
@c German node Prüfoptionen für myisamchk
@subsubsection Prüfoptionen für @code{myisamchk}

@cindex Prüfoptionen, myisamchk
@cindex Tabellen, prüfen

@table @code
@item -c oder --check
Tabelle auf Fehler überprüfen. Das ist die vorgabemäßige Operation, wenn
Sie @code{myisamchk} keine sonstigen Optionen angeben, die dies
überschreiben.

@item -e oder --extend-check
Tabelle SEHR gründlich prüfen (was recht langsam ist, wenn Sie viele Indexe
haben). Diese Option sollte nur in Extremfällen benutzt werden.
Normalerweise sollten @code{myisamchk} oder @code{myisamchk --medium-check}
in fast allen Fällen in der Lage sein, herauszufinden, ob es in der Tabelle
irgend welche Fehler gibt.

Wenn Sie @code{--extended-check} benutzen und viel Arbeitsspeicher haben,
setzen Sie den Wert von @code{key_buffer_size} um etliches herauf!

@item -F oder --fast
Nur Tabellen prüfen, die nicht ordnungsgemäß geschlossen wurden.
@item -C oder --check-only-changed
Nur Tabellen prüfen, die seit der letzten Prüfung geändert wurden.
@item -f oder --force
@code{myisamchk} mit @code{-r} (repair) auf die Tabelle neu starten, wenn
@code{myisamchk} in der Tabelle irgend welche Fehler findet.
@item -i oder --information
Statistische Informationen über die Tabelle, die geprüft wird, ausgeben.
@item -m oder --medium-check
Schneller als extended-check, findet aber nur 99,99% aller Fehler. Das
sollte allerdings in den meisten Fällen ausreichen.
@item -U oder --update-state
In der @file{.MYI}-Datei speichern, wann die Tabelle geprüft wurde und ob
die Tabelle beschädigt wurde. Das sollte benutzt werden, um vollen Nutzen
aus der @code{--check-only-changed}-Option ziehen zu können. Sie sollten
diese Option nicht benutzen, wenn der @code{mysqld}-Server die Tabelle
benutzt und Sie ihn mit @code{--skip-locking} laufen lassen.
@item -T oder --read-only
Die Tabelle nicht als geprüft kennzeichnen. Das ist hilfreich, wenn Sie
@code{myisamchk} benutzen, um eine Tabelle zu prüfen, die von irgend einer
anderen Applikation benutzt wird, die kein Sperren durchführt (wie
@code{mysqld --skip-locking}).
@end table


@node myisamchk repair options, myisamchk other options, myisamchk check options, Table maintenance
@c German node Reparaturoptionen für myisamchk
@subsubsection Reparaturoptionen für @code{myisamchk}

@cindex Reparaturoptionen, myisamchk
@cindex Dateien, reparieren

Folgende Optionen werden benutzt, wenn Sie @code{myisamchk} mit @code{-r}
oder @code{-o} starten:

@table @code
@item -D # oder --data-file-length=#
Maximale Länge der Daten-Datei (wenn die Daten-Datei neu erzeugt wird, wenn
sie 'voll' ist).
@item -e oder --extend-check
Es wird versucht, jede mögliche Zeile der Daten-Datei wiederherzustellen.
Normalerweise wird dies auch eine Menge Zeilen-'Müll' finden. Benutzen Sie
diese Option nur dann, wenn Sie völlig verzweifelt sind.
@item -f oder --force
Alte temporäre Dateien (@code{tabelle.TMD}) werden überschrieben, anstatt
abzubrechen.
@item -k # oder keys-used=#
Wenn Sie ISAM benutzen, weist das den ISAM-Tabellen-Handler an, nur die
ersten @code{#}-Indexe zu benutzen. Wenn Sie @code{MyISAM} benutzen, sagt
es dem Handler, welche Schlüssel benutzt werden sollen, wobei jedes
Binärbit für einen Schlüssel steht (der erste Schlüssel ist Bit 0). Das
kann benutzt werden, um schnelleres Einfügen (Insert) zu erreichen!
Deaktivierte Indexe können reaktiviert werden, indem man @code{myisamchk
-r} benutzt.
@item -l oder --no-symlinks
Symbolischen Links wird nicht gefolgt. Normalerweise repariert
@code{myisamchk} die Tabelle, auf die ein Symlink verweist. Diese Option
gibt es in MySQL 4.0 nicht, weil MySQL 4.0 während der Reparatur keine
Symlinks entfernt.
@item -r oder --recover
Kann fast alles reparieren, ausser eindeutige Schlüssel, die nicht
eindeutig sind (was ein extrem unwahrscheinlicher Fehler bei ISAM- /
MyISAM-Tabellen ist). Wenn Sie eine Tabelle wiederherstellen wollen,
sollten Sie zuerst diese Option ausprobieren. Nur wenn myisamchk berichtet,
dass die Tabelle mit @code{-r} nicht wiederhergestellt werden kann, sollten
Sie @code{-o} probieren. (Hinweis: Im unwahrscheinlichen Fall, dass
@code{-r} fehlschlägt, ist die Daten-Datei immer noch intakt.) Wenn Sie
viel Arbeitsspeicher haben, sollten Sie die Größe von
@code{sort_buffer_size} herauf setzen!
@item  -o oder --safe-recover
Benutzt eine alte Wiederherstellungsmethode (liest alle Zeilen der Reihe
nach und aktualisiert alle Indexbäume, basierend auf den gefundenen
Zeilen); das ist sehr viel langsamer als @code{-r}, kann aber eine Reihe
sehr unwahrscheinlicher Fälle behandeln, die @code{-r} nicht behandeln
kann. Diese Wiederherstellungsmethode benutzt viel weniger Plattenspeicher
als @code{-r}. Normalerweise sollte man immer zuerst versuchen, mit
@code{-r} zu reparieren und nur im Falle des Fehlschlagens @code{-o}
benutzen.

Wenn Sie viel Arbeitsspeicher haben, sollten Sie die Größe von
@code{key_buffer_size} herauf setzen!
@item -n oder --sort-recover
Zwingt @code{myisamchk} zu sortieren, um Schlüssel aufzulösen, selbst wenn
die temporären Dateien sehr Groß sein sollten. Diese Option hat keine
Auswirkung, wenn Sie Volltextschlüssel in der Tabelle haben.

@item --character-sets-dir=...
Verzeichnis, wo Zeichensätze gespeichert sind.
@item --set-character-set=name
Ändert den Zeichensatz, der vom Index benutzt wird.
@item -t oder --tmpdir=path
Pfad zum Speichern temporärer Dateien. Wenn dieser nicht gesetzt ist,
benutzt @code{myisamchk} hierfür die Umgebungsvariable @code{TMPDIR}.
@item -q oder --quick
Repariert schneller, indem die Daten-Datei nicht verändert wird. Man kann
ein zweites @code{-q} angeben, um @code{myisamchk} zu zwingen, die
Original-Daten-Datei zu ändern, falls doppelte Schlüssel auftreten.
@item -u oder --unpack
Datei entpacken, die mit myisampack gepackt wurde.
@end table


@node myisamchk other options, myisamchk memory, myisamchk repair options, Table maintenance
@c German node Andere Optionen für myisamchk
@subsubsection Weitere Optionen für @code{myisamchk}

Weitere Aktionen, die @code{myisamchk} ausführen kann, neben der Prüfung
und Reparatur von Tabellen:

@table @code
@item -a oder --analyze
Analysiert die Verteilung von Schlüsseln. Das verbessert die Performance
bei Tabellenverknüpfungen (Joins), indem der Join-Optimierer in die Lage
versetzt wird, besser auszuwählen, in welcher Reihenfolge die Tabellen
verknüpft werden sollten und welche Schlüssel er dabei verwenden sollte:
@code{myisamchk --describe --verbose tabelle'} oder Benutzung von
@code{SHOW KEYS} in MySQL.
@item -d oder --description
Gibt ein paar Informationen über die Tabelle aus.
@item -A oder --set-auto-increment[=value]
Zwingt auto_increment, mit diesem oder einem höheren Wert anzufangen. Wenn
kein Wert angegeben wird, wird der nächste auto_increment-Wert auf den
höchsten benutzten Wert für den auto-Schlüssel + 1 gesetzt.
@item -S oder --sort-index
Sortiert die Blöcke des Indexbaums in Hoch-Niedrig-Reihenfolge. Das
optimiert Suchoperationen und macht das Durchsehen (Scanning) von Tabellen
nach Schlüsseln schneller.
@item -R oder --sort-records=#
Sortiert Datensätze in Übereinstimmung mit einem Index. Das macht Ihre
Daten viel konzentrierter und kann @code{SELECT} mit Bereichen und
@code{ORDER BY}-Operationen auf diesem Index erheblich beschleunigen. (Beim
ersten Sortieren kann das SEHR langsam sein!) Um die Anzahl von Indexen
einer Tabelle herauszufinden, benutzen Sie @code{SHOW INDEX}, was die
Indexe einer Tabelle in genau der Reihenfolge zeigt, in der
@code{myisamchk} sie sieht. Indexe werden mit 1 beginnend nummeriert.
@end table


@node myisamchk memory, Crash recovery, myisamchk other options, Table maintenance
@c German node Speicher bei myisamchk
@subsubsection Speicherbenutzung von @code{myisamchk}

@cindex memory usage, myisamchk

Die Speicherzuordnung ist wichtig, wenn Sie @code{myisamchk} laufen lassen.
@code{myisamchk} benutzt nicht mehr Speicher, als Sie mir der
@code{-O}-Option festlegen. Wenn Sie @code{myisamchk} für sehr große
Dateien benutzen wollen, sollten Sie zuerst entscheiden, wieviel Speicher
Sie benutzen wollen. Die Vorgabe liegt bei nur etwa 3 MB, um Dinge zu
reparieren. Indem größere Werte benutzt werden, können Sie
@code{myisamchk} dazu bringen, schneller zu arbeiten. Wenn Sie
beispielsweise 32 MB Arbeitsspeicher haben, könnten Sie Optionen wie die
folgende benutzen (zusätzlich zu weiteren Optionen, die Sie eventuell
angeben):

@example
shell> myisamchk -O sort=16M -O key=16M -O read=1M -O write=1M ...
@end example

@code{-O sort=16M} sollte für die meisten Fälle ausreichen.

Denken Sie daran, dass @code{myisamchk} temporäre Dateien in @code{TMPDIR}
benutzt. Wenn @code{TMPDIR} auf ein Speicher-Dateisystem zeigt, können
Kein-Speicher-Fehler schnell auftreten. Wenn das passiert, setzen Sie
@code{TMPDIR} so, dass es auf ein Verzeichnis mit mehr Speicherplatz zeigt
und starten Sie @code{myisamchk} erneut.

Beim Reparieren benötigt @code{myisamchk} große Mengen von
Festplattenspeicher:

@itemize @bullet
@item
Die doppelte Größe der Daten-Datei (die Originaldatei und eine Kopie).
Dieser Platz wird nicht benötigt, wenn die Reparatur mit @code{--quick}
durchgeführt wird, weil in diesem Fall nur die Index-Datei neu erzeugt
wird. Der Platz wird auf derselben Festplatte benötigt, wo die
Original-Daten-Datei liegt!
@item
Platz für die neue Index-Datei, die die alte ersetzt. Die alte Index-Datei
wird beim Start beschnitten, daher kann man diesen Platz üblicherweise
ignorieren. Der Platz wird auf derselben Platte benötigt, auf der die
Original-Index-Datei liegt!
@item
Wenn Sie @code{--recover} oder @code{--sort-recover} benutzen (aber nicht,
wenn Sie @code{--safe-recover} benutzen), brauchen Sie Platz für einen
Sortierpuffer (Sort Buffer) für:
@code{(größter_schlüssel + zeilen_zeiger_länge) * anzahl_der_zeilen * 2}.
Sie können die Länge der Schlüssel und die Zeilen-Zeiger-Länger mit
@code{myisamchk -dv tabelle} prüfen.
Dieser Platz wird auf der temporären Platte zugeordnet (festgelegt durch
@code{TMPDIR} oder @code{--tmpdir=#}).
@end itemize

Wenn Sie während der Reparatur ein Problem mit dem Plattenplatz bekommen,
können Sie @code{--safe-recover} anstelle von @code{--recover}
ausprobieren.


@node Crash recovery, Check, myisamchk memory, Table maintenance
@c German node Fehlerbeseitigung nach Abstürzen
@subsubsection Benutzung von @code{myisamchk} für die Fehlerbeseitigung nach Abstürzen

@cindex Absturz, Wiederherstellung
@cindex Wiederherstellung, nach Absturz

Wenn Sie @code{mysqld} mit @code{--skip-locking} laufen lassen (was auf
einigen Systemen wie Linux die Vorgabe ist), können Sie @code{myisamchk}
nicht zuverlässig dafür benutzen, eine Tabelle zu prüfen, wenn
@code{mysqld} diese Tabelle benutzt. Wenn Sie sicher sein können, dass
niemand auf die Tabellen mit @code{mysqld} zugreift, während Sie
@code{myisamchk} laufen lassen, müssen Sie nur ein @code{mysqladmin
flush-tables} durchführen, bevor Sie anfangen, die Tabellen zu prüfen. Wenn
Sie das nicht garantieren können, müssen Sie @code{mysqld} herunter fahren,
während Sie die Tabellen prüfen. Wenn Sie @code{myisamchk} laufen lassen,
währen @code{mysqld} die Tabellen aktualisiert, erhalten Sie möglicherweise
die Meldung, dass eine Tabelle beschädigt ist, selbst wenn sie es nicht
ist.

Wenn Sie @code{--skip-locking} nicht benutzen, können Sie jederzeit
@code{myisamchk} benutzen, um Tabellen zu prüfen. Während Sie das tun,
warten alle Clients, die versuchen, die Tabelle zu aktualisieren, bis
@code{myisamchk} fertig ist, bevor sie weiter machen.

Wenn Sie @code{myisamchk} benutzen, um Tabellen zu reparieren oder zu
optimieren, @strong{MÜSSEN} Sie stets sicherstellen, dass der
@code{mysqld}-Server die Tabelle nicht benutzt (das trifft auch zu, wenn
Sie @code{--skip-locking} benutzen). Wenn Sie @code{mysqld} nicht herunter
fahren, sollten Sie zumindest @code{mysqladmin flush-tables} ausführen,
bevor Sie @code{myisamchk} benutzen.

Dieses Kapitel beschreibt, wie man MySQL-Datenbanken auf Datenbeschädigung
prüft und damit umgeht. Wenn Ihre Tabellen häufig beschädigt sind, wollten
Sie versuchen, den Grund hierfür herauszufinden! @xref{Crashing}.

Der Abschnitt über @code{MyISAM}-Tabellen enthält Gründe, warum eine
Tabelle beschädigt sein könnte. @xref{MyISAM table problems}.

Wenn Sie eine Wiederherstellung nach einem Absturz durchführen, ist es
wichtig zu wissen, das jede Tabelle @code{tabelle} in einer Datenbank mit
drei Dateien im Datenbank-Verzeichnis korrespondiert:

@multitable @columnfractions .2 .8
@item @strong{Datei} @tab @strong{Zweck}
@item @file{tabelle.frm} @tab Tabellendefinitionsdatei (form)
@item @file{tabelle.MYD} @tab Daten-Datei (data)
@item @file{tabelle.MYI} @tab Index-Datei (index)
@end multitable

Jeder der drei Dateitypen kann auf verschiedene Weisen beschädigt werden.
Probleme treten aber zumeist bei Daten-Dateien und Index-Dateien auf.

@code{myisamchk} funktioniert so, dass Zeile für Zeile eine Kopie der
@file{.MYD}-(data)-Datei gemacht wird. Es beendet die Reparaturphase damit,
dass die alte @file{.MYD}-Datei entfernt wird und die neue Datei mit dem
Orginal-Dateinamen benannt wird. Wenn Sie @code{--quick} benutzen, erzeugt
@code{myisamchk} keine temporäre @file{.MYD}-Datei, sondern nimmt statt
dessen an, dass die @file{.MYD}-Datei korrekt ist, und erzeugt nur eine
neue Index-Datei, ohne die @file{.MYD}-Datei zu berühren. Das ist sicher,
weil @code{myisamchk} automatisch feststellt, wenn die @file{.MYD}-Datei
beschädigt ist, und die Reparatur in diesem Fall abbricht. Sie können
@code{myisamchk} auch mit zwei @code{--quick}-Optionen aufrufen. In diesem
Fall bricht @code{myisamchk} bei einigen Fehlern (wie doppelten
Schlüsseleinträgen) nicht ab, sondern versucht statt dessen, diese
aufzulösen, indem die @file{.MYD}-Datei verändert wird. Normalerweise ist
die Benutzung von zwei @code{--quick}-Optionen nur sinnvoll, wenn Sie zu
wenig frei Plattenplatz haben, um eine normale Reparatur durchzuführen. In
diesem Fall sollten Sie zumindest eine Datensicherung machen, bevor Sie
@code{myisamchk} laufen lassen.


@node Check, Repair, Crash recovery, Table maintenance
@c German node Prüfung
@subsubsection Wie Tabellen auf Fehler überprüft werden

@cindex Prüfen, Tabellen auf Fehler
@cindex Tabellen, Fehlerprüfung
@cindex Fehler, Tabellen prüfen auf

Um eine MyISAM-Tabelle zu prüfen, benutzen Sie folgende Befehle:

@table @code
@item myisamchk tabelle
Das findet 99.99% aller Fehler. Nicht gefunden werden Beschädigungen, die
@strong{NUR} die Daten-Datei betreffen (was sehr ungewöhnlich ist). Wenn
Sie eine Tabelle prüfen wollen, sollten Sie @code{myisamchk} normalerweise
ohne Optionen oder entweder mit der @code{-s}- oder @code{--silent}-Option
laufen lassen.

@item myisamchk -m tabelle
Das findet 99.999% aller Fehler. Zuerst prüft es alle Indexeinträge auf
Fehler und liest dann alle Zeilen durch. Es berechnet eine Prüfsumme für
alle Schlüssel in den Zeilen und bestätigt dann, dass die Prüfsumme mit der
Prüfsumme für die Schlüssel im Indexbaum übereinstimmt.

@item myisamchk -e tabelle
Das führt eine vollständige, gründlich Prüfung aller Daten durch (@code{-e}
bedeutet ``extended check'' - erweiterte Prüfung). Es führt ein Prüf-Lesen
jedes Schlüssels für jede Zeile durch, um zu bestätigen, dass sie
tatsächlich auf die richtige Zeile verweisen. Das kann bei einer großen
Tabelle mit vielen Schlüsseln SEHR LANG dauern. @code{myisamchk} hält
normalerweise an, wenn es den ersten Fehler gefunden hat. Wenn Sie mehr
Informationen haben wollen, können Sie die
@code{--verbose}-(@code{-v})-Option benutzen. Das veranlasst
@code{myisamchk}, weiterzumachen, bis maximal 20 Fehler gefunden wurden.
Bei normalem Gebrauch ist ein einfaches @code{myisamchk} (ohne weitere
Argumente ausser dem Tabellennamen) ausreichend.

@item myisamchk -e -i tabelle
Wie der vorherige Befehl, jedoch weist die @code{-i}-Option
@code{myisamchk} an, zusätzlich einige statistische Informationen
auszugeben.
@end table


@node Repair, Optimisation, Check, Table maintenance
@c German node Reparatur
@subsubsection Wie Tabellen repariert werden

@cindex Tabellen, Reparatur
@cindex Reparatur, Tabellen

Der folgende Abschnitt behandelt nur die Benutzung von @code{myisamchk} mit
@code{MyISAM}-Tabellen (Erweiterungen @code{.MYI} und @code{.MYD}). Wenn
Sie @code{ISAM}-Tabellen benutzen (Erweiterungen @code{.ISM} und
@code{.ISD}), sollten Sie statt dessen @code{isamchk} benutzen.

Ab MySQL-Version 3.23.14 können Sie MyISAM-Tabellen mit dem
@code{REPAIR TABLE}-Befehl reparieren. @xref{REPAIR TABLE}.

Zu den Symptomen einer beschädigten Tabelle gehören Anfragen, die
unerwartet abbrechen, und beobachtbare Fehler wie folgender:

@itemize @bullet
@item
@file{tabelle.frm} is locked against change
@item
Can't find file @file{tabelle.MYI} (Errcode: ###)
@item
Unexpected end of file
@item
Record file is crashed
@item
Got error ### from table handler

Um mehr Information über den Fehler zu erhalten, lassen Sie @code{perror
###} laufen. Hier sind die häufigsten Fehler, die auf ein Problem mit der
Tabelle hinweisen:

@example
shell> perror 126 127 132 134 135 136 141 144 145
126 = Index-Datei ist beschädigt / falsches Dateiformat
127 = Daten-Datei ist beschädigt
132 = Alte Datenbank-Datei
134 = Datensatz wurde bereits gelöscht (oder Daten-Datei beschädigt)
135 = Kein Platz mehr in der Daten-Datei
136 = Kein Platz mehr in der Index-Datei
141 = Doppelter Eintrag für eindeutigen Schlüssel oder Beschränkung beim Schreiben oder Aktualisiern
144 = Tabelle ist beschädigt und die letzte Reparatur ist fehlgeschlagen
145 = Tabelle ist als beschädigt gekennzeichnet und sollte repariert werden
@end example

Beachten Sie, dass Fehler 135 (kein Platz mehr in der Daten-Datei) kein
Fehler ist, der durch eine einfache Reparatur behoben werden kann. In
diesem Fall müssen Sie folgendes durchführen:

@example
ALTER TABLE tabelle MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
@end example

@end itemize

In den anderen Fällen müssen Sie Ihre Tabellen reparieren. @code{myisamchk}
kann üblicherweise die meisten Dinge, die schief gehen können, finden und
beheben.

Der Reparaturprozess läuft in vier Phasen ab, die unten beschrieben sind.
Bevor Sie anfangen, sollten Sie in das Datenbank-Verzeichnis wechseln und
die Berechtigungen der Tabellen-Dateien prüfen. Stellen Sie sicher, dass
diese durch den Unix-Benutzer lesbar sind, unter dem @code{mysqld} läuft
(und für Sie, weil Sie auf die Dateien zugreifen müssen, wenn Sie sie
prüfen). Wenn Sie in der Folge Dateien verändern müssen, müssen diese für
Sie auch schreibbar sein.

Wenn Sie MySQL-Version 3.23.16 und höher benutzen, können (und sollten) Sie
die @code{CHECK}- und @code{REPAIR}-Befehle benutzen, um
@code{MyISAM}-Tabellen zu prüfen und zu reparieren. @xref{REPAIR TABLE}.

Der Handbuchabschnitt über Tabellenwartung beinhaltet die Optionen für
@code{isamchk} / @code{myisamchk}. @xref{Table maintenance}.

Der folgende Abschnitt ist für Fälle, in denen die obigen Befehle
fehlschlagen, oder wenn Sie die erweiterten Features benutzen wollen, die
@code{isamchk} / @code{myisamchk} zur Verfügung stellt.

Wenn Sie eine Tabelle von der Kommandozeile aus reparieren wollen, müssen
Sie zuerst den @code{mysqld}-Server herunter fahren. Beachten Sie bei
@code{mysqladmin shutdown} auf einen entfernten Server, dass der
@code{mysqld}-Server noch für eine Weile aktiv bleibt, nachdem
@code{mysqladmin} beendet ist, bis alle Anfragen beendet und alle Schlüssel
auf Platte zurück geschrieben (flush) wurden.

@noindent
@strong{Phase 1: Prüfen Ihrer Tabellen}

Lassen Sie @code{myisamchk *.MYI} laufen, oder @code{myisamchk -e *.MYI},
wenn Sie mehr Zeit haben. Benutzen Sie die @code{-s}-(silent)-Option, um
unnötige Informationen zu unterdrücken.

Wenn der @code{mysqld}-Server herunter gefahren ist, sollten Sie die
@code{--update}-Option benutzen, um @code{myisamchk} zu veranlassen, die
Tabelle als 'geprüft' zu kennzeichnen.

Sie müssen nur die Tabellen reparieren, bei denen @code{myisamchk} bekannt
gibt, dass sie Fehler enthalten. Gehen Sie bei solchen Tabellen zu Phase 2
über.

Wenn Sie beim Prüfen merkwürdige Fehler erhalten (wie @code{out of
memory}-Fehler), oder wenn @code{myisamchk} abstürzt, gehen Sie zu Phase
3.

@noindent
@strong{Phase 2: Einfache, sichere Reparatur}

HINWEIS: Wenn Sie wollen, dass die Reparatur sehr viel schneller abläuft,
sollten Sie allen @code{isamchk/myisamchk}-Befehlen folgendes hinzufügen:
@code{-O sort_buffer=# -O key_buffer=#} (wobei # etwa 1/4 des verfügbaren
Arbeitsspeichers ist).

Probieren Sie zuerst @code{myisamchk -r -q tabelle} (@code{-r -q} bedeutet
``quick recovery mode'' - schnelles Wiederherstellen). Dies versucht, die
Index-Datei zu reparieren, ohne die Daten-Datei zu berühren. Wenn die
Daten-Datei alles enthält, was sie sollte, und die Löschverknüpfungen auf
die korrekten Stellen in der Daten-Datei zeigen, sollte das funktionieren
und die Tabelle ist repariert. Machen Sie dann mit der Reparatur der
nächsten Tabelle weiter. Ansonsten führen Sie folgende Prozedur durch:

@enumerate
@item
Machen Sie eine Datensicherung der Daten-Datei, bevor Sie fortfahren.

@item
Geben Sie @code{myisamchk -r tabelle} (@code{-r} bedeutet ``recovery mode''
- Wiederherstellung) ein. Das entfernt falsche und gelöschte Datensätze aus
der Daten-Datei und stellt die Index-Datei wieder her.

@item
Wenn die vorherigen Schritte fehlschlagen, geben Sie @code{myisamchk
--safe-recover tabelle} ein. Der Modus für sicheres Wiederherstellen
benutzt eine alte Wiederherstellungsmethode, die ein paar Fälle behandelt,
die der normale Wiederherstellungsmodus nicht behandelt (ist aber
langsamer).
@end enumerate

Wenn Sie bei der Reparatur merkwürdige Fehler erhalten (wie @code{out of
memory}-Fehler), oder wenn @code{myisamchk} abstürzt, gehen Sie zu Phase
3.

@noindent
@strong{Phase 3: Schwierige Reparatur}

Diese Phase sollten Sie nur dann erreichen, wenn der erste 16-KB-Block der
Index-Datei zerstört ist oder falsche Informationen enthält, oder wenn die
Index-Datei fehlt. In diesem Fall ist es notwendig, eine neue Index-Datei
zu erzeugen. Das machen Sie wie folgt:

@enumerate
@item
Verschieben Sie die Daten-Datei an einen sicheren Ort.

@item
Benutzen Sie die Tabellen-Beschreibungsdatei, um eine neue (leere)
Daten-Datei und Index-Dateien zu erzeugen:

@example
shell> mysql datenbank
mysql> SET AUTOCOMMIT=1;
mysql> TRUNCATE TABLE tabelle;
mysql> quit
@end example

Wenn Ihre SQL-Version kein @code{TRUNCATE TABLE} hat, benutzen Sie statt
dessen @code{DELETE FROM tabelle}.

@item
Kopieren Sie Ihre alte Daten-Datei zurück, über die neu erzeugte
Daten-Datei. (Verschieben Sie Ihre alte Daten-Datei nicht einfach, damit
Sie eine Kopie erhalten, falls etwas schief geht.)
@end enumerate

Gehen Sie zurück zu Phase 2. @code{myisamchk -r -q} sollte jetzt
funktionieren. (Das sollte keine Endlosschleife sein.)

@noindent
@strong{Phase 4: Sehr schwierige Reparatur}

Diese Phase sollten Sie nur dann erreichen, wenn auch die
Beschreibungsdatei beschädigt ist. Das sollte nie passieren, weil die
Beschreibungsdatei nicht verändert wird, nachdem die Tabelle erzeugt wurde:

@enumerate
@item
Stellen Sie die Beschreibungsdatei von einer Datensicherung wieder her und
gehen Sie zurück zu Phase 3. Sie können auch die Index-Datei
wiederherstellen und zu Phase 2 zurück gehen.  Im letzteren Fall sollten
Sie mit @code{myisamchk -r} anfangen.

@item
Wenn Sie keine Datensicherung haben, aber genau wissen, wie die Tabelle
erzeugt wurde, erzeugen Sie eine Kopie der Tabelle in einer anderen
Datenbank. Entfernen Sie die neue Daten-Datei und verschieben Sie die
Beschreibungs- und Index-Dateien von der anderen Datenbank in Ihre
beschädigte Datenbank. Das ergibt neue Beschreibungs- und Index-Dateien,
läßt aber die Daten-Datei in Ruhe. Gehen Sie zurück zu Phase 2 und
versuchen Sie, die Index-Datei wiederherzustellen.
@end enumerate


@node Optimisation,  , Repair, Table maintenance
@c German node Optimierung
@subsubsection Tabellenoptimierung

@cindex Tabellen, Optimierung
@cindex Optimierung, Tabellen

Um fragmentierte Datensätze zu vereinigen und verschwendeten Speicherplatz
zu beseitigen, der sich durch Löschen und Aktualisieren von Datensätzen
ergibt, lassen Sie @code{myisamchk} im Wiederherstellungsmodus laufen:

@example
shell> myisamchk -r tabelle
@end example

Auf dieselbe Weise können Sie eine Tabelle optimieren, indem Sie das
SQL-Statement @code{OPTIMIZE TABLE} benutzen. @code{OPTIMIZE TABLE} führt
eine Reparatur der Tabelle und eine Analyse der Schlüssel durch und
sortiert den Indexbaum, um schnelleres Nachschlagen der Schlüssel (Key
Lookup) zu ermöglichen. Ausserdem schaltet es die Möglichkeit ungewollter
Interaktionen zwischen einem Dienstprogramm und dem Server aus, weil der Server
bei der Benutzung von @code{OPTIMIZE TABLE} die ganze Arbeit verrichtet.
@xref{OPTIMIZE TABLE}.

@code{myisamchk} hat eine Anzahl weiterer Optionen, die Sie für die
Verbesserung der Performance einer Tabelle benutzen können:

@table @code
@item -S, --sort-index
@item -R index_nummer, --sort-records=index_nummer
@item -a, --analyze
@end table

Eine detaillierte Beschreibung der Optionen steht unter
@xref{myisamchk syntax}.


@node Maintenance regimen, Table-info, Table maintenance, Disaster Prevention
@c German node Wartungsplan
@subsection Wartungsplan für Tabellen erstellen

@cindex Wartung, Tabellen
@cindex Tabellen, Wartungsplan

Ab MySQL-Version 3.23.13 können Sie MyISAM-Tabellen mit dem @code{CHECK
TABLE}-Befehl prüfen. @xref{CHECK TABLE}. Sie können Tabellen mit dem
@code{REPAIR TABLE}-Befehl reparieren. @xref{REPAIR TABLE}.

Es ist eine gute Idee, Tabellenüberprüfungen auf regelmäßiger Basis
durchzuführen statt darauf zu warten, dass Probleme auftreten. Für
Wartungszwecke benutzen Sie @code{myisamchk -s}, um Tabellen zu überprüfen.
Die @code{-s}-Option (Kurzform für @code{--silent}) veranlasst
@code{myisamchk}, im schweigsamen Modus zu laufen, wobei Meldungen nur
ausgegeben werden, wenn Fehler auftreten.

@tindex .pid-(process ID)-Datei
Ebenfalls eine gute Idee ist es, Tabellen zu überprüfen, wenn der Server
hoch fährt. Wenn beispielsweise die Maschine mitten während einer
Aktualisierung (Update) neu gebootet hat, müssen Sie üblicherweise alle
Tabellen prüfen, die betroffen sein könnten. (Das ist ein Fall von
``erwarteter Tabellenbeschädigung''.) Sie können @code{safe_mysqld} einen
Test hinzufügen, der @code{myisamchk} laufen läßt, um alle Tabellen zu
überprüfen, die innerhalb der letzten 24 Stunden geändert wurden, wenn nach
einem Reboot eine alte @file{.pid}-(process ID)-Datei übrig blieb. (Die
@file{.pid}-Datei wird von @code{mysqld} erzeugt, wenn er hoch fährt, und
entfernt, wenn er normal beendet wird. Die Anwesenheit einer
@file{.pid}-Datei beim Systemstart zeigt an, dass @code{mysqld} regelwidrig
abgebrochen wurde.)

Eine noch bessere Testmethode besteht darin, jede Tabelle zu prüfen, deren
Zeit der letzten Änderung neuer ist als die der @file{.pid}-Datei.

Ausserdem sollten Sie Ihre Tabellen regelmäßig während der normalen
Systemtätigkeit prüfen. Bei MySQL AB lassen wir einen @code{cron}-Job
laufen, um alle wichtigen Tabellen einmal pro Woche zu prüfen, indem wir
folgende Zeile in der @file{crontab}-Datei benutzen:

@example
35 0 * * 0 /pfad/zu/myisamchk --fast --silent /pfad/zu/datadir/*/*.MYI
@end example

Das gibt Informationen über beschädigte Tabellen aus, so dass wir diese
prüfen und reparieren können, falls notwendig.

Da wir mittlerweile seit einigen Jahren keinerlei unerwartet beschädigte
Tabellen hatten (Tabellen, die aus anderen Gründen als Hardware-Schäden
beschädigt wurden), reicht uns einmal pro Woche völlig aus.

Wir empfehlen, dass Sie jede Nacht @code{myisamchk -s} auf alle Tabellen
ausführen, die während der letzten 24 Stunden aktualisiert wurden, bis Sie
MySQL so sehr vertrauen, wie wir selbst das mittlerweile tun.

@cindex Tabellen, defragmentieren
Normalerweise brauchen Sie MySQL-Tabellen nicht so sehr warten. Wenn Sie
Tabellen mit Zeilen dynamischer Länge ändern (Tabellen mit
@code{VARCHAR}-, @code{BLOB}- oder @code{TEXT}-Spalten) oder Tabellen mit
vielen gelöschten Zeilen haben, werden Sie diese von Zeit zu Zeit (einmal
im Monat?) defragmentieren wollen bzw. freien Speicherplatz schaffen.

Das können Sie mit @code{OPTIMIZE TABLE} auf die in Frage kommenden
Tabellen tun, oder, wenn Sie den @code{mysqld}-Server für eine Weile
herunter fahren können:

@example
isamchk -r --silent --sort-index -O sort_buffer_size=16M */*.ISM
myisamchk -r --silent --sort-index  -O sort_buffer_size=16M */*.MYI
@end example


@node Table-info,  , Maintenance regimen, Disaster Prevention
@c German node Tabelleninformation
@subsection Informationen über eine Tabelle erhalten

@cindex Tabellen, Informationen

Um eine Beschreibung einer Tabelle oder Statistiken über sie zu erhalten,
benutzen Sie die unten stehenden Befehle. Einige davon werden später
detaillierter erläutert:

@table @code
@item myisamchk -d tabelle
Läßt @code{myisamchk} im ``Beschreibungsmodus'' laufen, um eine
Beschreibung Ihrer Tabelle zu erzeugen. Wenn Sie den MySQL-Server mit der
@code{--skip-locking}-Option starten, kann @code{myisamchk} eventuell
Fehler über eine Tabelle berichten, die aktualisiert wird, während es
läuft. Weil @code{myisamchk} jedoch im Beschreibungsmodus keine Tabelle
ändert, gibt es kein Risiko, dass Daten zerstört werden.

@item myisamchk -d -v tabelle
Um mehr Informationen über das, was @code{myisamchk} tut, zu erzeugen,
fügen Sie @code{-v} als Option hinzu, damit es im geschwätzigen Modus
läuft.

@item myisamchk -eis tabelle
Zeigt nur die wichtigsten Informationen über die Tabelle. Das ist langsam,
weil es die ganze Tabelle lesen muss.

@item myisamchk -eiv tabelle
Wie @code{-eis}, sagt aber zusätzlich, was getan werden muss.
@end table

@cindex Beispiele, @code{myisamchk}-Ausgabe
@cindex @code{myisamchk}, Beispiele der Ausgabe
Beispiel einer @code{myisamchk -d}-Ausgabe:
@example
MyISAM file:     firma.MYI
Record format:   Fixed length
Data records:    1403698 Deleted blocks:         0
Recordlength:    226

table description:
Key Start Len Index   Type
1   2     8   unique  double
2   15    10  multip. text packed stripped
3   219   8   multip. double
4   63    10  multip. text packed stripped
5   167   2   multip. unsigned short
6   177   4   multip. unsigned long
7   155   4   multip. text
8   138   4   multip. unsigned long
9   177   4   multip. unsigned long
    193   1           text
@end example

Beispiel einer @code{myisamchk -d -v}-Ausgabe:
@example
MyISAM file:         firma
Record format:       Fixed length
File-version:        1
Creation time:       1999-10-30 12:12:51
Recover time:        1999-10-31 19:13:01
Status:              checked
Data records:           1403698  Deleted blocks:              0
Datafile parts:         1403698  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     3
Max datafile length: 3791650815  Max keyfile length: 4294967294
Recordlength:               226

table description:
Key Start Len Index   Type                  Rec/key     Root Blocksize
1   2     8   unique  double                      1 15845376      1024
2   15    10  multip. text packed stripped        2 25062400      1024
3   219   8   multip. double                     73 40907776      1024
4   63    10  multip. text packed stripped        5 48097280      1024
5   167   2   multip. unsigned short           4840 55200768      1024
6   177   4   multip. unsigned long            1346 65145856      1024
7   155   4   multip. text                     4995 75090944      1024
8   138   4   multip. unsigned long              87 85036032      1024
9   177   4   multip. unsigned long             178 96481280      1024
    193   1           text
@end example

Beispiel einer @code{myisamchk -eis}-Ausgabe:
@example
Checking MyISAMDatei: firma
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:  98%  Packed:   17%

Records:          1403698    M.recordlength:     226   Packed:             0%
Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 639, Involuntary context switches 28966
@end example

Beispiel einer @code{myisamchk -eiv}-Ausgabe:
@example
Checking MyISAM file: firma
Data records: 1403698   Deleted blocks:       0
- check file-size
- check delete-chain
block_size 1024:
index  1:
index  2:
index  3:
index  4:
index  5:
index  6:
index  7:
index  8:
index  9:
No recordlinks
- check index reference
- check data record references index: 1
Key:  1:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 2
Key:  2:  Keyblocks used:  98%  Packed:   50%  Max levels:  4
- check data record references index: 3
Key:  3:  Keyblocks used:  97%  Packed:    0%  Max levels:  4
- check data record references index: 4
Key:  4:  Keyblocks used:  99%  Packed:   60%  Max levels:  3
- check data record references index: 5
Key:  5:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 6
Key:  6:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 7
Key:  7:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 8
Key:  8:  Keyblocks used:  99%  Packed:    0%  Max levels:  3
- check data record references index: 9
Key:  9:  Keyblocks used:  98%  Packed:    0%  Max levels:  4
Total:    Keyblocks used:   9%  Packed:   17%

- check records und index references
[LOTS OF ROW NUMBERS DELETED]

Records:          1403698    M.recordlength:     226   Packed:             0%
Recordspace used:     100%   Empty space:          0%  Blocks/Record:   1.00
Record blocks:    1403698    Delete blocks:        0
Recorddata:     317235748    Deleted data:         0
Lost space:             0    Linkdata:             0

User time 1639.63, System time 251.61
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 10580, Swaps 0
Blocks in 4 out 0, Messages in 0 out 0, Signals 0
Voluntary context switches 10604, Involuntary context switches 122798
@end example

Hier stehen die Größen der Daten- und Index-Dateien der Tabelle, die in
den vorstehenden Beispielen benutzt wurde:

@example
-rw-rw-r--   1 monty    tcx     317235748 Jan 12 17:30 firma.MYD
-rw-rw-r--   1 davida   tcx      96482304 Jan 12 18:35 firma.MYM
@end example

Erläuterungen der Informationen, die @code{myisamchk} erzeugt, werden unten
gegeben. ``keyfile'' ist die Index-Datei. ``Record'' und ``row'' sind
Synonyme:

@table @code
@item ISAM file
Name der ISAM-(Index)-Datei.

@item Isam-version
Version des ISAM-Formats. Momentan immer 2.

@item Creation time
Wann die Daten-Datei erzeugt wurde.

@item Recover time
Wann die Index-/Daten-Datei das letzte Mal rekonstruiert wurden.

@item Data records
Wie viele Datensätze in der Tabelle sind.

@item Deleted blocks
Wie viele gelöschte Blöcke noch Platz belegen.
Sie können Ihre Tabelle optimieren, um diesen Platz zu minimieren.
@xref{Optimisation}.

@item Datafile: Parts
Bei dynamischem Datensatzformat zeigt dies an, wie viele Datenblöcke es
gibt. Bei einer optimierten Tabelle ohne fragmentierte Datensätze ist das
dasselbe wie @code{Data records}.

@item Deleted data
Wie viele Bytes nicht zurückgewonnener gelöschter Daten es gibt.
Sie können Ihre Tabelle optimieren, um diesen Platz zu minimieren.
@xref{Optimisation}.

@item Datafile pointer
Die Größe des Daten-Datei-Zeigers in Bytes. Das sind normalerweise 2, 3, 4
oder 5 Bytes. Die meisten Tabellen schaffen 2 Bytes, aber das kann bislang
von MySQL noch nicht gesteuert werden. Bei festen Tabellen ist das eine
Datensatzadresse. Bei dynamischen Tabellen ist es eine Byte-Adresse.

@item Keyfile pointer
Die Größe des Index-Datei-Zeigers in Bytes. Sie beträgt normalerweise 1, 2
oder 3 Bytes. Die meisten Tabellen schaffen 2 Bytes, aber das wird von
MySQL automatisch berechnet. Es ist immer die Block-Adresse.

@item Max datafile length
Wie lang die Daten-Datei (@code{.MYD}-Datei) der Tabelle werden kann, in
Bytes.

@item Max keyfile length
Wie lang die Index-Datei (@code{.MYI}-Datei) der Tabelle werden kann, in
Bytes.

@item Recordlength
Wie viel Platz jeder Datensatz benötigt, in Bytes.

@item Record format
Das Format, das benutzt wird, um Tabellenzeilen zu speichern.
Die oben stehenden Beispiele benutzen @code{Fixed length}.
Andere mögliche Werte sind @code{Compressed} und @code{Packed}.

@item Table description
Eine Liste aller Schlüssel in der Tabelle. Für jeden Schlüssel werden
einige Low-Level-Informationen angezeigt:

@table @code
@item Key
Die Nummer des Schlüssels.

@item Start
Wo im Datensatz dieser Index-Teil anfängt.

@item Len
Wie lang dieser Index-Teil ist. Bei gepackten Zahlen sollte das immer die
gesamte Länge der Spalte sein. Bei Zeichenketten kann es kürzer als die
gesamte Länge der indizierten Spalte sein, weil Sie ein Prefix einer
Zeichenkettenspalte indexieren können.

@item Index
@code{unique} oder @code{multip.} (multiple). Zeigt an, ob ein Wert einmal
oder mehrfach in diesem Index vorkommen darf.

@item Type
Welchen Datentyp dieser Index-Teil hat. Das ist ein ISAM-Datentyp mit den
Optionen @code{packed}, @code{stripped} oder @code{empty}.

@item Root
Adresse des Root-Index-Blocks.

@item Blocksize
Die Größe jedes Index-Blocks. Vorgabemäßig ist das 1024, doch dieser Wert
kann beim Kompilieren geändert werden.

@item Rec/key
Das ist ein statistischer Wert, der vom Optimierer benutzt wird. Es sagt
aus, wie viele Datensätze es pro Wert für diesen Schlüssel gibt. Ein
eindeutiger Schlüssel hat immer einen Wert von 1. Das kann aktualisiert
werden, nachdem eine Tabelle geladen wurde (oder in größerem Umfang
geändert) mit @code{myisamchk -a}. Wenn dies überhaupt nicht aktualisiert
wurde, wird ein Wert von 30 angenommen.
@end table

@item
Im ersten Beispiel oben ist der neunte Schlüssel ein mehrteiliger Schlüssel
mit zwei Teilen.

@item Keyblocks used
Welcher Prozentsatz von Schlüsselblöcken benutzt wird. Weil die Tabellen,
die in den Beispielen benutzt wurden, direkt vorher mit @code{myisamchk}
reorganisiert wurden, sind diese Werte sehr hoch (sehr nahe am
theoretischen Maximum).

@item Packed
MySQL versucht, Schlüssel mit einem gemeinsamen Suffix zu packen. Das geht
nur bei @code{CHAR}-, @code{VARCHAR} und @code{DECIMAL}-Schlüsseln. Bei
langen Zeichenketten wie Namen kann das den benutzten Platz signifikant
verringern. Im dritten Beispiel oben ist der vierte Schlüssel zehn Zeichen
lang, wodurch ein 60%-ige Verringerung des Platzbedarfs erreicht wird.

@item Max levels
Wie tief der B-Baum für diesen Schlüssel ist. große Tabellen mit langen
Schlüsseln haben hohe Werte.

@item Records
Wie viele Zeilen in der Tabelle enthalten sind.

@item M.recordlength
Die durchschnittliche Datensatzlänge. Bei Tabellen mit Datensätzen fester
Länge ist das die exakte Datensatzlänge.

@item Packed
MySQL schneidet Leerzeichen am Ende von Zeichenketten ab. Der
@code{Packed}-Wert zeigt an, welcher Prozentsatz dadurch gespart wurde.

@item Recordspace used
Welcher Prozentsatz der Daten-Datei benutzt wird.

@item Empty space
Welcher Prozentsatz der Daten-Datei unbenutzt ist.

@item Blocks/Record
Durchschnittliche Anzahl der Blöcke pro Datensatz (das heißt, aus wie
vielen Verknüpfungen (Links) ein fragmentierter Datensatz zusammengesetzt
ist). Bei Tabellen mit festem Format ist das immer 1. Dieser Wert sollte so
nah wie möglich an 1,0 bleiben. Wenn er zu Groß wird, können Sie die
Tabelle @code{myisamchk} reorganisieren.
@xref{Optimisation}.

@item Recordblocks
Wie viele Blöcke (Verknüpfungen, Links) benutzt werden. Bei festem Format
ist das die Anzahl der Datensätze.

@item Deleteblocks
Wie viele Blöcke (Verknüpfungen, Links) gelöscht sind.

@item Recorddata
Wie viele Bytes in der Daten-Datei benutzt sind.

@item Deleted data
Wie viele Bytes in der Daten-Datei gelöscht sind (unbenutzt).

@item Lost space
Wenn ein Datensatz auf eine kürzere Länge aktualisiert wird, geht etwas
Platz verloren. Das ist die Summe aller solcher Verluste in Bytes.

@item Linkdata
When das dynamische Tabellenformat benutzt wird, werden Datensatzfragmente
mit Zeigern (Pointer) verknüpft (jeder mit 4 bis 7 Bytes). @code{Linkdata}
ist die Summe des Speicherplatzes, der von diesen Zeigern benutzt wird.
@end table

Wenn eine Tabelle mit @code{myisampack} komprimiert wurde, gibt
@code{myisamchk -d} zusätzliche Informationen über jede Tabellenspalte aus,
siehe @ref{myisampack, , @code{myisampack}}, wo sich ein Beispiel solcher
Informationen und was sie bedeuten befindet.


@node Database Administration, Localisation, Disaster Prevention, MySQL Database Administration
@c German node Datenbankadministration
@section Datenbankverwaltung Sprachreferenz




@menu
* OPTIMIZE TABLE::              
* ANALYZE TABLE::               
* FLUSH::                       
* KILL::                        
* SHOW::                        
@end menu

@node OPTIMIZE TABLE, ANALYZE TABLE, Database Administration, Database Administration
@c German node OPTIMIZE TABLE
@subsection @code{OPTIMIZE TABLE}-Syntax

@findex OPTIMIZE TABLE

@cindex Tabellen, defragmentieren
@cindex Tabellen, Fragmentierung

@example
OPTIMIZE TABLE tabelle[,tabelle]...
@end example

@code{OPTIMIZE TABLE} sollte benutzt werden, wenn Sie große Teile der
Tabelle gelöscht haben oder bei Tabellen mit Zeilen variabler Länge viele
Änderungen durchgeführt haben (Tabellen, die @code{VARCHAR}-, @code{BLOB}-
oder @code{TEXT}-Spalten enthalten). Gelöschte Datensätze werden in einer
verknüpften Liste vorgehalten, und nachfolgenden @code{INSERT}-Operationen
benutzen die Positionen alter Datensätze. Sie können @code{OPTIMIZE TABLE}
benutzen, um unbenutzten Platz freizugeben und die Daten-Datei zu
defragmentieren.

Momentan funktioniert @code{OPTIMIZE TABLE} nur auf @strong{MyISAM}- und 
@code{BDB}-Tabellen. Bei @code{BDB}-Tabellen ist @code{OPTIMIZE TABLE}
momentan auf @code{ANALYZE TABLE} gemappt. @xref{ANALYZE TABLE}.

Sie können @code{OPTIMIZE TABLE} auf andere Tabellentypen zum Laufen
bringen, indem Sie @code{mysqld} mit @code{--skip-new} oder
@code{--safe-mode} starten, aber in diesem Fall wird @code{OPTIMIZE TABLE}
lediglich auf @code{ALTER TABLE} gemappt.

@code{OPTIMIZE TABLE} funktioniert wie folgt:
@itemize @bullet
@item
Wenn die Tabelle gelöschte oder aufgeteilte Zeilen hat, wird sie repariert.
@item
Wenn die Index-Seiten nicht sortiert sind, werden sie sortiert.
@item
Wenn die Statistiken nicht aktuell sind (und eine Reparatur nicht durch das
Sortieren des Indexes durchgeführt werden könnte), werden sie aktualisiert.
@end itemize

@code{OPTIMIZE TABLE} für @code{MyISAM}-Tabellen ist äquivalent zum
Laufenlassen von @code{myisamchk --quick --check-changed-tables
--sort-index --analyze} auf die Tabelle.

Beachten Sie, dass die Tabelle während der Zeit, in der @code{OPTIMIZE TABLE} läuft, gesperrt ist!


@node ANALYZE TABLE, FLUSH, OPTIMIZE TABLE, Database Administration
@c German node ANALYZE TABLE
@subsection @code{ANALYZE TABLE}-Syntax

@findex ANALYZE TABLE

@example
ANALYZE TABLE tabelle[,tabelle...]
@end example

Analysiert und speichert die Schlüsselverteilung der Tabelle. Während der
Analyse ist die Tabelle mit einer Lesesperre gesperrt. Das funktioniert auf
@code{MyISAM} und @code{BDB}-Tabellen.

Das ist äquivalent zum Laufenlassen von @code{myisamchk -a} auf die
Tabelle.

MySQL benutzt die gespeicherte Schlüsselverteilung, um zu entscheiden, in
welcher Reihenfolge Tabellen verknüpft werden sollen, wenn man eine
Verknüpfung (Join) auf irgend etwas anderes als eine Konstante macht.

Der Befehl gibt eine Tabelle mit folgenden Spalten zurück:

@multitable @columnfractions .35 .65
@item @strong{Spalte} @tab @strong{Wert}
@item Table @tab Tabellenname.
@item Op @tab Immer ``analyze''.
@item Msg_type @tab @code{status}, @code{error}, @code{info} oder @code{warning}.
@item Msg_text @tab Die Meldung.
@end multitable

Sie können die gespeicherte Schlüsselverteilung mit dem @code{SHOW
INDEX}-Befehl überprüfen. @xref{SHOW DATABASE INFO}.

Wenn die Tabelle seit dem letzten @code{ANALYZE TABLE}-Befehl nicht
geändert wurde, wird sie nicht noch einmal analysiert.


@node FLUSH, KILL, ANALYZE TABLE, Database Administration
@c German node FLUSH
@subsection @code{FLUSH}-Syntax

@findex FLUSH

@cindex @code{mysqladmin}
@cindex Löschen, Caches
@cindex Caches, löschen

@example
FLUSH flush_option [,flush_option]
@end example

Wenn Sie einige der internen Caches, die MySQL benutzt, löschen wollen,
benutzen Sie den @code{FLUSH}-Befehl. Um @code{FLUSH} ausführen zu können,
müssen Sie die @strong{RELOAD}-Berechtigung haben.

@code{flush_option} kann eine der folgenden sein:

@multitable @columnfractions .15 .85
@item @code{HOSTS}  @tab Leert die Host-Cache-Tabellen. Sie sollten die
Host-Tabellen flushen, wenn einige Ihrer Hosts die IP-Nummer ändern oder
wenn Sie die Fehlermeldung @code{Host ... is blocked} erhalten.  Wenn mehr
als @code{max_connect_errors} Fehler in einer Zeile für einen gegebenen
Host während der Verbindung zum MySQL-Server vorkommen, nimmt MySQL an,
dass etwas nicht stimmt und blockiert den Host von weiteren
Verbindungsversuchen. Wenn die Host-Tabellen geflusht werden, gestattet das
dem Host, einen erneuten Verbindungsversuch zu machen.
@c German FIX unwrapped @xref
@xref{Blocked host}. Sie können @code{mysqld} mit @code{-O
max_connection_errors=999999999} starten, um diese Fehlermeldung zu
vermeiden.

@item @code{LOGS} @tab Schließt alle Log-Dateien und öffnet sie danach
wieder. Wenn Sie die Update-Log-Datei oder eine binäre Log-Datei ohne
Erweiterung angegeben haben, wird die Erweiterungsnummer der Log-Datei um
eins relativ zur vorherigen Datei hoch gezählt. Wenn Sie eine Erweiterung
im Dateinamen benutzt haben, schließt MySQL die Update-Log-Datei und
öffnet sie danach wieder. @xref{Update log}. Das ist dasselbe, wie
dem @code{mysqld}-Server das @code{SIGHUP}-Signal senden.

@item @code{PRIVILEGES} @tab Lädt die Berechtigungen aus den
Berechtigungstabellen der @code{mysql}-Datenbank neu.

@item @code{TABLES} @tab Schließt alle offenen Tabellen und erzwingt, dass
alle Tabellen in Benutzung geschlossen werden.

@item @code{[TABLE | TABLES] tabelle [,tabelle...]} @tab Flusht nur die
angegebenen Tabellen.

@item @code{TABLES WITH READ LOCK} @tab Schließt alle offenen Tabellen und
sperrt alle Tabellen aller Datenbanken mit einer Lesesperre, bis man
@code{UNLOCK TABLES} ausführt. Das ist eine sehr bequeme Möglichkeit,
Datensicherungen zu erzeugen, wenn Sie ein Dateisystem wie Veritas haben,
das Schnappschüsse aufnehmen kann.

@item @code{STATUS} @tab Setzt alle Status-Variablen auf null zurück. Das
sollte man nur benutzen, wenn man eine Anfrage debuggt.
@end multitable

Jeden der oben genannten Befehle können Sie auch mit dem
@code{mysqladmin}-Dienstprogramm ausführen, indem Sie @code{flush-hosts},
@code{flush-logs}, @code{reload} oder @code{flush-tables}-Befehle
eingeben.

Sehen Sie sich auch den @code{RESET}-Befehl an, der bei der Replikation
benutzt wird. @xref{Replication SQL}.



@node KILL, SHOW, FLUSH, Database Administration
@c German node KILL
@subsection @code{KILL}-Syntax

@findex KILL

@cindex @code{mysqladmin}

@example
KILL Thread_id
@end example

Jede Verbindung zu @code{mysqld} läuft durch einen separaten Thread. Sie
können sehen, welche Threads laufen, indem Sie den @code{SHOW
PROCESSLIST}-Befehl ausführen, und einen Thread killen, indem Sie den
@code{KILL Thread_id}-Befehl ausführen.

Wenn Sie die @strong{process}-Berechtigung haben, können Sie alle Threads
sehen und killen. Ansonsten können Sie nur Ihre eigenen Threads sehen und
killen.

Sie können auch die @code{mysqladmin processlist}- und @code{mysqladmin
kill}-Befehle benutzen, um Threads einzusehen und zu killen.

Wenn Sie ein @code{KILL} ausführen, wird ein Thread-spezifischer @code{kill
flag} für den Thread gesetzt.

In den meisten Fällen kann es einige Zeit dauern, bis der Thread stirbt,
weil der kill-Flag nur in bestimmten Intervallen geprüft wird:

@itemize @bullet
@item
Bei @code{SELECT}-, @code{ORDER BY}- und @code{GROUP BY}-Schleifen wird der
Flag geprüft, nachdem ein Block von Zeilen gelesen wurde. Wenn der
kill-Flag gesetzt ist, wird das Statement abgebrochen.
@item
Bei @code{ALTER TABLE} wird der kill-Flag geprüft, bevor jeder Block von
Zeilen aus der Original-Tabelle gelesen wird. Wenn der Flag gesetzt ist,
wird der Befehl abgebrochen und die temporäre Tabelle wird gelöscht.
@item
Bei @code{UPDATE TABLE} und @code{DELETE TABLE} wird der kill-Flag geprüft,
nachdem jeder Block gelesen wurde sowie nach jeder aktualisierten oder
gelöschten Zeile. Wenn der Flag gesetzt ist, wird das Statement
abgebrochen. Beachten Sie, dass die Änderungen nicht zurück gerollt
(Rollback) werden, wenn Sie keine Transaktionen benutzen!
@item
@code{GET_LOCK()} wird mit @code{NULL} abgebrochen.
@item
Ein @code{INSERT DELAYED}-Thread flusht schnell alle Zeilen, die er im
Speicher hat, und stirbt.
@item
Wenn der Thread im Tabellen-Lock-Handler ist (Status: @code{Locked}), wird
die Tabellen-Sperre schnell abgebrochen.
@item
Wenn der Thread bei einem @code{write}-Aufruf auf freien Plattenplatz
wartet, wird der Schreibvorgang mit einer Meldung, dass die Platte voll
ist, abgebrochen.
@end itemize




@node SHOW,  , KILL, Database Administration
@c German node SHOW
@subsection @code{SHOW}-Syntax

@findex SHOW DATABASE INFO
@findex SHOW DATABASES
@findex SHOW TABLES
@findex SHOW COLUMNS
@findex SHOW FIELDS
@findex SHOW INDEX
@findex SHOW KEYS
@findex SHOW STATUS
@findex SHOW VARIABLES
@findex SHOW PROCESSLIST
@findex SHOW TABLE STATUS
@findex SHOW GRANTS
@findex SHOW CREATE TABLE
@findex SHOW MASTER STATUS
@findex SHOW MASTER LOGS
@findex SHOW SLAVE STATUS

@example
   SHOW DATABASES [LIKE platzhalter]
oder SHOW [OPEN] TABLES [FROM datenbank] [LIKE platzhalter]
oder SHOW [FULL] COLUMNS FROM tabelle [FROM datenbank] [LIKE platzhalter]
oder SHOW INDEX FROM tabelle [FROM datenbank]
oder SHOW TABLE STATUS [FROM datenbank] [LIKE platzhalter]
oder SHOW STATUS [LIKE platzhalter]
oder SHOW VARIABLES [LIKE platzhalter]
oder SHOW LOGS
oder SHOW [FULL] PROCESSLIST
oder SHOW GRANTS FOR benutzer
oder SHOW CREATE TABLE tabelle
oder SHOW MASTER STATUS
oder SHOW MASTER LOGS
oder SHOW SLAVE STATUS
@end example

@code{SHOW} stellt Informationen über Datenbanken, Tabellen, Spalten oder
Status-Informationen über den Server zur Verfügung. Wenn der @code{LIKE
platzhalter}-Teil benutzt wird, kann die @code{platzhalter}-Zeichenkette
eine Zeichenkette sein, die die SQL-@samp{%}- und @samp{_}-
Platzhalterzeichen benutzt.



@menu
* SHOW DATABASE INFO::          
* SHOW TABLE STATUS::           
* SHOW STATUS::                 
* SHOW VARIABLES::              
* SHOW LOGS::                   
* SHOW PROCESSLIST::            
* SHOW GRANTS::                 
* SHOW CREATE TABLE::           
@end menu

@node SHOW DATABASE INFO, SHOW TABLE STATUS, SHOW, SHOW
@c German node SHOW DATABASE INFO
@subsubsection Informationen über Datenbank, Tabellen, Spalten und Indexe abrufen

@cindex Anzeigen, Informationen, @code{SHOW}

Sie können @code{datenbank.tabelle} als Alternative zur @code{tabelle FROM
datenbank}-Syntax benutzen. Diese beiden Statements sind äquivalent:

@example
mysql> SHOW INDEX FROM tabelle FROM datenbank;
mysql> SHOW INDEX FROM datenbank.tabelle;
@end example

@code{SHOW DATABASES} listet die Datenbanken auf dem MySQL-Server-Host auf.
Diese Liste erhalten Sie auch mit dem @code{mysqlshow}-Befehl.

@code{SHOW TABLES} listet die Tabellen in einer gegebenen Datenbank auf.
Sie erhalten diese Liste auch mit dem @code{mysqlshow datenbank}-Befehl.

@strong{HINWEIS:} Wenn ein Benutzer keinerlei Berechtigungen für eine
Tabelle hat, wird die Tabelle in der Ausgabe von @code{SHOW TABLES} oder
@code{mysqlshow datenbank} nicht aufgeführt.

@code{SHOW OPEN TABLES} listet die Tabellen auf, die momentan im
Tabellen-Cache geöffnet sind. @xref{Open tables}. Das @code{Comment}-Feld
zeigt an, wie oft die Tabelle gecachet (@code{cached}) und in Benutzung
(@code{in_use}) ist.

@code{SHOW COLUMNS} listet die Spalten in einer gegebenen Tabelle auf. Wenn
Sie die @code{FULL}-Option angeben, erhalten Sie auch die Berechtigungen,
die Sie für jede Spalte besitzen. Wenn die Spaltentypen von dem abweichen,
was Sie erwarten, nämlich, was Sie im @code{CREATE TABLE}-Statement
angegeben haben, beachten Sie, dass MySQL manchmal Spaltentypen ändert.
@xref{Silent column changes}.

Das @code{DESCRIBE}-Statement gibt ähnliche Informationen wie @code{SHOW
COLUMNS} aus. @xref{DESCRIBE, , @code{DESCRIBE}}.

@code{SHOW FIELDS} ist ein Synonym für @code{SHOW COLUMNS}. @code{SHOW
KEYS} ist ein Synonym für @code{SHOW INDEX}. Sie können die Spalten oder
Indexe einer Tabelle auch mit @code{mysqlshow Datenbanktabelle} oder
@code{mysqlshow -k Datenbanktabelle} anzeigen.

@code{SHOW INDEX} gibt die Index-Informationen in einem Format aus, das dem
@code{SQLStatistics}-Aufruf in ODBC stark ähnelt. Folgende Spalten werden
zurückgegeben:

@multitable @columnfractions .35 .65
@item @strong{Spalte}            @tab @strong{Bedeutung}
@item @code{Table}               @tab Name der Tabelle.
@item @code{Non_unique}          @tab 0, wenn der Index keine Duplikate enthalten darf.
@item @code{Key_name}            @tab Name des Indexes.
@item @code{Seq_in_index}        @tab Spaltensequenznummer im Index, zählt ab 1.
@item @code{Column_name}         @tab Spaltenname.
@item @code{Collation}           @tab Wie die Spalte im Index sortiert ist.
                                      In MySQL können diese Werte @samp{A} (Ascending - aufsteigend)
                                      oder @code{NULL} (Not sorted - unsortiert) sein.
@item @code{Cardinality}         @tab Anzahl der eindeutigen Werte im Index.
                                      Dieser Wert wird durch Laufenlassen von @code{isamchk -a} aktualisiert.
@item @code{Sub_part}            @tab Anzahl der indizierten Zeichen, wenn die Spalte nur teilweise indiziert ist.
                                      @code{NULL}, wenn der gesamte Schlüssel indiziert ist.
@item @code{Comment}             @tab Verschiedene Anmerkungen. Momentan teilt es nur mit,
                                      ob der Index FULLTEXT ist oder nicht.
@end multitable

Beachten Sie: Weil @code{Cardinality} basierend auf statistischen Werten
gezählt wird, die als Ganzzahlen gespeichert sind, ist es nicht
notwendigerweise bei kleinen Tabellen korrekt.


@node SHOW TABLE STATUS, SHOW STATUS, SHOW DATABASE INFO, SHOW
@c German node SHOW TABLE STATUS
@subsubsection @code{SHOW TABLE STATUS}

@cindex anzeigen, Tabellen-Status
@cindex Tabellen, Status anzeigen
@cindex Status, Tabellen

@example
SHOW TABLE STATUS [FROM datenbank] [LIKE platzhalter]
@end example

@code{SHOW TABLE STATUS} (neu in Version 3.23) funktioniert wie @code{SHOW
STATUS}, zeigt aber viele weitere Informationen über jede Tabelle. Diese
Liste erhalten Sie auch mit dem @code{mysqlshow --status datenbank}-Befehl.
Folgende Spalten werden zurückgegeben:

@multitable @columnfractions .30 .70
@item @strong{Spalte} @tab @strong{Bedeutung}
@item @code{Name} @tab Name der Tabelle.
@item @code{Type} @tab Typ der Tabelle. @xref{Table types}.
@item @code{Row_format} @tab Das Zeilenspeicherformat (fest, dynamisch oder komprimiert).
@item @code{Rows} @tab Anzahl der Zeilen.
@item @code{Avg_row_length} @tab Durchschnittliche Zeilenlänge.
@item @code{Data_length} @tab Länge der Daten-Datei.
@item @code{Max_data_length} @tab Maximale Länge der Daten-Datei.
@item @code{Index_length} @tab Länge der Index-Datei.
@item @code{Data_free} @tab Anzahl der zugewiesenen (allocated), aber nicht benutzten Bytes.
@item @code{Auto_increment} @tab Nächster autoincrement-Wert.
@item @code{Create_time} @tab Wann die Tabelle erzeugt wurde.
@item @code{Update_time} @tab Wann die Daten-Datei das letzte Mal aktualisiert wurde.
@item @code{Check_time} @tab Wann die Tabelle das letzte Mal geprüft wurde.
@item @code{Create_options} @tab Zusätzliche Optionen, die beim @code{CREATE TABLE} benutzt wurden.
@item @code{Comment} @tab Der Kommentar, der beim Erzeugen der Tabelle angegeben wurde (oder einige Informationen, warum MySQL nicht auf die Tabelleninformationen zugreifen konnte).
@end multitable

Bei @code{InnoDB}-Tabellen wird im Tabellenkommentar der freie Platz im
Tablespace ausgegeben.


@node SHOW STATUS, SHOW VARIABLES, SHOW TABLE STATUS, SHOW
@c German node SHOW STATUS
@subsubsection @code{SHOW STATUS}

@cindex @code{mysqladmin}
@code{SHOW STATUS} zeigt Server-Status-Informationen an (wie
@code{mysqladmin extended-status}). Die Ausgabe ähnelt der unten stehenden,
obwohl Format und Anzahl der Zeilen wahrscheinlich abweichen:

@example
+--------------------------+------------+
| Variable_name            | Value      |
+--------------------------+------------+
| Aborted_clients          | 0          |
| Aborted_connects         | 0          |
| Bytes_received           | 155372598  |
| Bytes_sent               | 1176560426 |
| Connections              | 30023      |
| Created_tmp_disk_tables  | 0          |
| Created_tmp_tables       | 8340       |
| Created_tmp_files        | 60         |
| Delayed_insert_Threads   | 0          |
| Delayed_writes           | 0          |
| Delayed_errors           | 0          |
| Flush_commands           | 1          |
| Handler_delete           | 462604     |
| Handler_read_first       | 105881     |
| Handler_read_key         | 27820558   |
| Handler_read_next        | 390681754  |
| Handler_read_prev        | 6022500    |
| Handler_read_rnd         | 30546748   |
| Handler_read_rnd_next    | 246216530  |
| Handler_update           | 16945404   |
| Handler_write            | 60356676   |
| Key_blocks_used          | 14955      |
| Key_read_requests        | 96854827   |
| Key_reads                | 162040     |
| Key_write_requests       | 7589728    |
| Key_writes               | 3813196    |
| Max_used_connections     | 0          |
| Not_flushed_key_blocks   | 0          |
| Not_flushed_delayed_rows | 0          |
| Open_tables              | 1          |
| Open_files               | 2          |
| Open_streams             | 0          |
| Opened_tables            | 44600      |
| Questions                | 2026873    |
| Select_full_join         | 0          |
| Select_full_range_join   | 0          |
| Select_range             | 99646      |
| Select_range_check       | 0          |
| Select_scan              | 30802      |
| Slave_running            | OFF        |
| Slave_open_temp_tables   | 0          |
| Slow_launch_threads      | 0          |
| Slow_queries             | 0          |
| Sort_merge_passes        | 30         |
| Sort_range               | 500        |
| Sort_rows                | 30296250   |
| Sort_scan                | 4650       |
| Table_locks_immediate    | 1920382    |
| Table_locks_waited       | 0          |
| Threads_cached           | 0          |
| Threads_created          | 30022      |
| Threads_connected        | 1          |
| Threads_running          | 1          |
| Uptime                   | 80380      |
+--------------------------+------------+
@end example

@cindex variables, status
The status variables listed höher have the following Bedeutung:

@multitable @columnfractions .35 .65
@item @strong{Variable} @tab @strong{Bedeutung}
@item @code{Aborted_clients} @tab Anzahl der Verbindungen, die abgebrochen
wurden, weil der Client starb, ohne die Verbindung ordnungsgemäß zu
schließen. @xref{Communication errors}.
@item @code{Aborted_connects} @tab Anzahl der fehlgeschlagenen Versuche,
sich mit dem MySQL-Server zu verbinden. @xref{Communication errors}.
@item @code{Bytes_received} @tab Anzahl der Bytes, die von allen Clients
empfangen wurden.
@item @code{Bytes_sent} @tab Anzahl der Bytes, die an alle Clients gesendet
wurden.
@item @code{Connections} @tab Anzahl der Verbindungsversuche zum MySQL-Server.
@item @code{Created_tmp_disk_tables} @tab Anzahl der (implizit) auf der
Platte erzeugten temporären Tabellen bei der Ausführung von Statements.
@item @code{Created_tmp_tables} @tab Anzahl der (implizit) im
Arbeitsspeicher erzeugten temporären Tabellen bei der Ausführung von
Statements.
@item @code{Created_tmp_files} @tab Wie viele temporäre Dateien
@code{mysqld} erzeugt hat.
@item @code{Delayed_insert_Threads} @tab Anzahl der verzögerten
Insert-Handler-Threads in Benutzung.
@item @code{Delayed_writes} @tab Anzahl der Zeilen, die mit @code{INSERT
DELAYED} geschrieben wurden.
@item @code{Delayed_errors} @tab Anzahl der Zeilen, die mit @code{INSERT
DELAYED} geschrieben wurden, und bei denen irgend ein Fehler auftrat
(wahrscheinlich @code{duplicate key}).
@item @code{Flush_commands} @tab Anzahl der ausgeführten @code{FLUSH}-Befehle.
@item @code{Handler_delete} @tab Wie oft eine Zeile aus einer Tabelle
gelöscht wurde.
@item @code{Handler_read_first} @tab Wie oft der erste Eintrag aus einem
Index gelesen wurde. Wenn dieser Wert hoch ist, legt das nahe, dass der
Server viele komplette Index-Scans macht (zum Beispiel @code{SELECT spalte1
FROM foo}, unter der Annahme, dass spalte1 indiziert ist).
@item @code{Handler_read_key} @tab Anzahl der Anfragen, eine Zeile
basierend auf einem Schlüssel zu lesen. Wenn dieser Wert hoch ist, ist das
ein gutes Indiz dafür, dass Ihre Anfragen und Tabellen korrekt indiziert
sind.
@item @code{Handler_read_next} @tab Anzahl der Anfragen, die nächste Zeile
in der Reihenfolge des Schlüssels zu lesen. Dieser Wert wird herauf
gezählt, wenn Sie eine Index-Spalte mit einer Bereichsbeschränkung (Limit)
abfragen. Er wird ebenfalls herauf gezählt, wenn Sie einen Index-Scan
durchführen.
@item @code{Handler_read_rnd} @tab Anzahl der Anfragen, eine Zeile
basierend auf einer festen Position zu lesen. Dieser Wert wird hoch sein,
wenn Sie viele Anfragen ausführen, die erfordern, dass das Ergebnis
sortiert wird.
@item @code{Handler_read_rnd_next} @tab Anzahl der Anfragen, die nächste
Zeile in der Daten-Datei zu lesen. Dieser Wert wird hoch sein, wenn Sie
viele Tabellen-Scans durchführen. Im Allgemeinen weist das darauf hin, dass
Ihre Tabellen nicht korrekt indiziert sind, oder dass Ihre Anfragen nicht
so geschrieben sind, dass Sie Vorteile aus den Indexen ziehen, die Sie
haben.
@item @code{Handler_update} @tab Anzahl der Anfragen, eine Zeile in einer
Tabelle zu aktualisieren.
@item @code{Handler_write} @tab Anzahl der Anfragen, eine Zeile in eine
Tabelle einzufügen.
@item @code{Key_blocks_used} @tab Die Anzahl der benutzten Blocks im
Schlüssel-Cache.
@item @code{Key_read_requests} @tab Die Anzahl der Anfragen, einen
Schlüssel-Block aus dem Cache zu lesen.
@item @code{Key_reads} @tab Die Anzahl physikalischer Lesezugriffen eines
Schlüssel-Blocks von der Platte.
@item @code{Key_write_requests} @tab Die Anzahl der Anfragen, einen
Schlüssel-Block in den Cache zu schreiben.
@item @code{Key_writes} @tab Die Anzahl physikalischer Schreibvorgänge
eines Schlüssel-Blocks auf Platte.
@item @code{Max_used_connections} @tab Die höchste Anzahl von Verbindungen,
die gleichzeitig in Benutzung sind.
@item @code{Not_flushed_key_blocks} @tab Schlüssel-Blöcke im
Schlüssel-Cache, die verändert wurden, aber noch nicht auf die Platte
zurück geschrieben (flush).
@item @code{Not_flushed_delayed_rows} @tab Anzahl der Zeilen, die in
@code{INSERT DELAY}-Warteschleifen darauf warten, geschrieben zu werden.
@item @code{Open_tables} @tab Anzahl der offenen Tabellen.
@item @code{Open_files} @tab  Anzahl der offenen Dateien.
@item @code{Open_streams} @tab Anzahl der offenen Streams (hauptsächlich
zum Loggen benutzt).
@item @code{Opened_tables} @tab Anzahl der Tabellen, die geöffnet wurden.
@item @code{Select_full_join} @tab Anzahl der Joins ohne Schlüssel (sollte
0 sein).
@item @code{Select_full_range_join} @tab Anzahl der Joins, bei denen eine
Bereichssuche auf die Referenztabelle statt fand.
@item @code{Select_range} @tab Anzahl der Joins, bei denen Bereiche auf die
erste Tabelle benutzt wurden. (Es ist normalerweise unkritisch, wenn dieser
Wert hoch ist.)
@item @code{Select_scan} @tab Anzahl der Joins, bei denen die erste Tabelle
gescannt wurde.
@item @code{Select_range_check} @tab Anzahl der Joins ohne Schlüssel, bei
denen nach jeder Zeile auf Schlüsselbenutzung geprüft wurde (sollte 0
sein).
@item @code{Questions} @tab Anzahl der Anfragen, die zum Server geschickt
wurden.
@item @code{Slave_open_temp_tables} @tab Anzahl der temporären Tabellen,
die momentan vom Slave-Thread geöffnet sind.
@item @code{Slow_launch_threads} @tab Anzahl der Threads, die länger als
@code{slow_launch_time} brauchten, um sich zu verbinden.
@item @code{Slow_queries} @tab Anzahl der Anfragen, die länger als
@code{long_query_time} benötigten. @xref{Slow query log}.
@item @code{Sort_merge_passes} @tab Anzahl der Verschmelzungen (Merge), die
von einem Sortiervorgang benötigt wurden. Wenn dieser Wert hoch ist,
sollten Sie in Betracht ziehen, @code{sort_buffer} herauf zu setzen.
@item @code{Sort_range} @tab Anzahl der Sortiervorgänge, die mit Bereichen
durchgeführt wurden.
@item @code{Sort_rows}  @tab Anzahl der sortierten Zeilen.
@item @code{Sort_scan}  @tab Anzahl der Sortiervorgänge, die durchgeführt
wurden, indem die Tabelle gescannt wurde.
@item @code{Table_locks_immediate} @tab Wie oft eine Tabellensperre sofort
erlangt wurde. Verfügbar nach Version 3.23.33.
@item @code{Table_locks_waited} @tab Wie oft eine Tabellensperre nicht
sofort erlangt werden konnte und gewartet werden musst. Wenn dieser Wert
hoch ist und Sie Performance-Probleme haben, sollten Sie zunächst Ihre
Anfragen optimieren und dann entweder Ihre Tabelle(n) zerteilen oder
Replikation benutzen. Verfügbar nach Version 3.23.33.
@item @code{Threads_cached} @tab Anzahl der Threads im Thread-Cache.
@item @code{Threads_connected} @tab Anzahl der momentan offenen
Verbindungen.
@item @code{Threads_created} @tab Anzahl der Threads, die zur Handhabung
von Verbindungen erzeugt wurden.
@item @code{Threads_running} @tab Anzahl der Threads, die nicht schlafen.
@item @code{Uptime} @tab Seit wie vielen Sekunden der Server hoch gefahren
ist.
@end multitable

Einige Anmerkungen zum oben Aufgeführten:

@itemize @bullet
@item
Wenn @code{Opened_tables} hoch ist, ist Ihre @code{table_cache}-Variable
wahrscheinlich zu niedrig.
@item
Wenn @code{key_reads} hoch ist, ist Ihr @code{key_cache} wahrscheinlich zu
klein. Die Cache-Zugriffsrate kann mit @code{key_reads} /
@code{key_read_requests} berechnet werden.
@item
Wenn @code{Handler_read_rnd} hoch ist, haben Sie wahrscheinlich viele
Anfragen, die MySQL zwingen, ganze Tabellen zu scannen, oder Sie haben
Joins, die Schlüssel nicht richtig benutzen.
@item
Wenn @code{Threads_created} hoch ist, sollten Sie eventuell die
@code{Thread_cache_size}-Variable herauf setzen.
@item
Wenn @code{Created_tmp_disk_tables} hoch ist, sollten Sie eventuell die
@code{tmp_table_size}-Variable herauf setzen, damit temporäre Tabellen im
Speicher erzeugt werden statt auf der Platte.
@end itemize


@node SHOW VARIABLES, SHOW LOGS, SHOW STATUS, SHOW
@c German node SHOW VARIABLES
@subsubsection @code{SHOW VARIABLES}

@example
SHOW VARIABLES [LIKE platzhalter]
@end example

@code{SHOW VARIABLES} zeigt die Werte einiger MySQL-Systemvariablen. Sie
erhalten diese List auch mit dem @code{mysqladmin variables}-Befehl. Wenn
die Vorgabewerte unpassend sind, können Sie die meisten dieser Variablen
mit Kommandozeilenoptionen setzen, wenn Sie @code{mysqld} hoch fahren.
@xref{Command-line options}.

Die Ausgabe ähnelt der unten stehenden,
obwohl Format und Anzahl der Zeilen wahrscheinlich abweichen:

@example
+-------------------------+---------------------------+
| Variable_name           | Value                     |
+-------------------------+---------------------------+
| ansi_mode               | OFF                       |
| back_log                | 50                        |
| basedir                 | /my/monty/                |
| bdb_cache_size          | 16777216                  |
| bdb_log_buffer_size     | 32768                     |
| bdb_home                | /my/monty/data/           |
| bdb_max_lock            | 10000                     |
| bdb_logdir              |                           |
| bdb_shared_data         | OFF                       |
| bdb_tmpdir              | /tmp/                     |
| binlog_cache_size       | 32768                     |
| concurrent_insert       | ON                        |
| connect_timeout         | 5                         |
| datadir                 | /my/monty/data/           |
| delay_key_write         | ON                        |
| delayed_insert_limit    | 100                       |
| delayed_insert_timeout  | 300                       |
| delayed_queue_size      | 1000                      |
| flush                   | OFF                       |
| flush_time              | 0                         |
| have_bdb                | YES                       |
| have_innodb             | YES                       |
| have_raid               | YES                       |
| have_openssl            | NO                        |
| init_file               |                           |
| interactive_timeout     | 28800                     |
| join_buffer_size        | 131072                    |
| key_buffer_size         | 16776192                  |
| language                | /my/monty/share/english/  |
| large_files_support     | ON                        |
| log                     | OFF                       |
| log_update              | OFF                       |
| log_bin                 | OFF                       |
| log_slave_updates       | OFF                       |
| long_query_time         | 10                        |
| low_priority_updates    | OFF                       |
| lower_case_table_names  | 0                         |
| max_allowed_packet      | 1048576                   |
| max_binlog_cache_size   | 4294967295                |
| max_connections         | 100                       |
| max_connect_errors      | 10                        |
| max_delayed_threads     | 20                        |
| max_heap_table_size     | 16777216                  |
| max_join_size           | 4294967295                |
| max_sort_length         | 1024                      |
| max_tmp_tables          | 32                        |
| max_write_lock_count    | 4294967295                |
| myisam_recover_options  | DEFAULT                   |
| myisam_sort_buffer_size | 8388608                   |
| net_buffer_length       | 16384                     |
| net_read_timeout        | 30                        |
| net_retry_count         | 10                        |
| net_write_timeout       | 60                        |
| open_files_limit        | 0                         |
| pid_file                | /my/monty/data/donna.pid  |
| port                    | 3306                      |
| protocol_version        | 10                        |
| record_buffer           | 131072                    |
| query_buffer_size       | 0                         |
| safe_show_database      | OFF                       |
| server_id               | 0                         |
| skip_locking            | ON                        |
| skip_networking         | OFF                       |
| skip_show_database      | OFF                       |
| slow_launch_time        | 2                         |
| socket                  | /tmp/mysql.sock           |
| sort_buffer             | 2097116                   |
| table_cache             | 64                        |
| table_type              | MYISAM                    |
| Thread_cache_size       | 4                         |
| Thread_stack            | 65536                     |
| tmp_table_size          | 1048576                   |
| tmpdir                  | /tmp/                     |
| version                 | 3.23.29a-gamma-debug      |
| wait_timeout            | 28800                     |
+-------------------------+---------------------------+
@end example

Jede Option ist unten beschrieben. Die Werte für Puffergrößen, Längen und
Stack-Größen sind in Bytes angegeben. Sie können Wert mit den Suffixen
@samp{K} oder @samp{M} angeben, um Kilobytes oder Megabytes zu
kennzeichnen. @code{16M} zum Beispiel bedeutet 16 Megabytes. Bei den
Suffixen spielt Groß-/Kleinschreibung keine Rolle, @code{16M} und
@code{16m} sind äquivalent:

@cindex Variablen, Werte
@table @code
@item @code{ansi_mode}.
Ist @code{ON}, wenn @code{mysqld} mit @code{--ansi} gestartet wurde.
@xref{ANSI mode}.

@item @code{back_log}
Die Anzahl unerledigter Verbindungsanforderung, die MySQL haben kann. Dies
kommt ins Spiel, wenn der Haupt-Thread von MySQL @strong{SEHR} viele
Verbindungsanforderungen in sehr kurzer Zeit erhält. Dann dauert es etwas
(wenngleich sehr kurz), damit der Haupt-Thread die Verbindung prüfen und
einen neuen Thread starten kann. Der @code{back_log}-Wert zeigt an, wie
viele Verbindungen während dieser kurzen Zeit gestapelt (gestackt) werden können, bevor
MySQL für einen Moment aufhört, neue Anforderungen zu beantworten. Sie
brauchen diesen Wert nur dann herauf setzen, wenn Sie eine große Zahl von
Verbindungen in kurzer Zeit erwarten.

Mit anderen Worten ist dieser Wert die Größe der Listen-Queue
(Warteschlange) für herein kommende TCP/IP-Verbindungen. Ihr Betriebssystem
hat seine eigene Beschränkung hinsichtlich der Größe dieser Queue. Die
Handbuchseiten zum Unix-@code{listen(2)}-System sollten hier weitere
Details haben. Sehen Sie in der Dokumentation Ihres Betriebssystems nach,
wie hoch der Wert dieser Variablen maximal sein kann. Wenn Sie versuchen,
@code{back_log} höher als die Begrenzung Ihres Betriebssystems zu setzen,
ist das ineffektiv.

@item @code{basedir}
Der Wert der @code{--basedir}-Option.

@item @code{bdb_cache_size}
Der zugewiesene Puffer, um Index und Zeilen bei @code{BDB}-Tabellen zu
cachen. Wenn Sie keine @code{BDB}-Tabellen benutzen, sollten Sie
@code{mysqld} mit @code{--skip-bdb} starten, um für diesen Cache keinen
Arbeitsspeicher zu verschwenden.

@item @code{bdb_log_buffer_size}
Der zugewiesene Puffer, um Index und Zeilen bei @code{BDB}-Tabellen zu
cachen. Wenn Sie keine @code{BDB}-Tabellen benutzen, sollten Sie diesen
Wert auf o setzen und @code{mysqld} mit @code{--skip-bdb} starten, um für
diesen Cache keinen Arbeitsspeicher zu verschwenden.

@item @code{bdb_home}
Der Wert der @code{--bdb-home}-Option.

@item @code{bdb_max_lock}
Die maximale Anzahl von Sperren (Vorgabewert: 1000), die bei einer
@code{BDB}-Tabelle aktiv sein können. Sie sollten diesen Wert herauf
setzen, wenn Sie Fehler folgender Art bekommen: @code{bdb:
Lock table is out of available locks} oder @code{Got error 12 from ...},
wenn Sie lange Transaktionen durchführen oder wenn @code{mysqld} viele
Zeile untersuchen muss, um die Anfrage zu berechnen.

@item @code{bdb_logdir}
Der Wert der @code{--bdb-logdir}-Option.

@item @code{bdb_shared_data}
Ist @code{ON}, wenn Sie @code{--bdb-shared-data} benutzen.

@item @code{bdb_tmpdir}
Der Wert der @code{--bdb-tmpdir}-Option.

@item @code{binlog_cache_size}. Die Größe des Caches, in dem
SQL-Statements für das Binär-Log während einer Transaktion vorgehalten
werden. Wenn Sie oft große, aus vielen Statements bestehende Transaktionen
durchführen, können Sie diesen Wert herauf setzen, um mehr Performance zu
erzielen. @xref{COMMIT}.

@item @code{character_set}
Der vorgabemäßige Zeichensatz.

@item @code{character_sets}
Die unterstützten Zeichensätze.

@item @code{concurrent_inserts}
Falls @code{ON} (Vorgabe), läßt MySQL @code{INSERT} auf
@code{MyISAM}-Tabellen zu, auf die zur gleichen Zeit @code{SELECT}-Anfragen
laufen. Sie können diese Option ausschalten, indem Sie @code{mysqld} mit
@code{--safe} oder @code{--skip-new} starten.

@cindex timeout
@item @code{connect_timeout}
Die Anzahl von Sekunden, die der @code{mysqld}-Server auf ein
Verbindungspaket wartet, bevor er mit @code{Bad handshake} antwortet.

@item @code{datadir}
Der Wert der @code{--datadir}-Option.

@item @code{delay_key_write}
Falls angeschaltet (Vorgabe), akzeptiert MySQL die
@code{delay_key_write}-Option von @code{CREATE TABLE}. Das heißt, dass der
Schlüsselpuffer für Tabellen bei dieser Option nicht bei jeder
Index-Aktualisierung auf Platte zurückgeschrieben (flush) wird, sondern
nur, wenn eine Tabelle geschlossen wird. Das beschleunigt Schreibvorgänge
auf Schlüssel ganz erheblich, aber Sie sollten eine automatische Prüfung
aller Tabellen mit @code{myisamchk --fast --force} hinzufügen, wenn Sie
diese Option benutzen. Beachten Sie: Wenn Sie @code{mysqld} mit der
@code{--delay-key-write-for-all-tables}-Option startet, heißt das, dass
alle Tabelle so behandelt werden, als wenn sie mit der
@code{delay_key_write}-Option erzeugt worden wären. Sie können diesen Flag
löschen, wenn Sie @code{mysqld} mit @code{--skip-new} oder
@code{--safe-mode} starten.

@item @code{delayed_insert_limit}
Nachdem @code{delayed_insert_limit} Zeilen eingefügt wurden, prüft der
@code{INSERT DELAYED}-Handler, ob noch irgend welche
@code{SELECT}-Statements anhängig sind. Falls ja, wird deren Ausführung
zugelassen, bevor weiter gemacht wird.

@item @code{delayed_insert_timeout}
Wie lange ein @code{INSERT DELAYED}-Thread auf @code{INSERT}-Statements
warten soll, bevor abgebrochen wird.

@item @code{delayed_queue_size}
Welche Warteschleifen-(Queue)-Speichergröße (in Zeilen) für die Handhabung
von @code{INSERT DELAYED} zugewiesen werden soll. Wenn die Queue voll ist,
wartet jeder Client, der @code{INSERT DELAYED} ausführt, bis es wieder
Platz in der Queue gibt.

@item @code{flush}
Ist @code{ON}, wenn Sie MySQL mit der @code{--flush}-Option gestartet
haben.

@item @code{flush_time}
Wenn diese Variable auf einen Wert ungleich 0 gesetzt wird, dann werden
alle @code{flush_time} Sekunden alle Tabelle geschlossen (um Ressourcen
frei zu geben und Dinge auf Platte zurück zu schreiben). Diese Option
empfehlen wir nur auf Windows 95, Windows 98 oder auf Systemen, auf denen
Sie sehr wenige Ressourcen haben.

@item @code{have_bdb}
Ist @code{YES}, wenn @code{mysqld} Berkeley-DB-Tabellen unterstützt. Ist
@code{DISABLED}, wenn @code{--skip-bdb} benutzt wird.
@item @code{have_innodb}
Ist @code{YES}, wenn @code{mysqld} InnoDB-Tabellen unterstützt. Ist
@code{DISABLED}, wenn @code{--skip-innodb} benutzt wird.
@item @code{have_raid}
Ist @code{YES}, wenn @code{mysqld} die @code{RAID}-Option unterstützt.
@item @code{have_openssl}
Ist @code{YES}, wenn @code{mysqld} SSL (Verschlüsselung) auf dem
Client-/Server-Protokoll unterstützt.

@item @code{init_file}
Der Name der Datei, die mit der @code{--init-file}-Option angegeben wurde,
als Sie den Server starteten. Das ist eine Datei mit SQL-Statements, die
der Server beim Start ausführen soll.

@item @code{interactive_timeout}
Die Anzahl von Sekunden, die der Server bei einer interaktiven Verbindung
wartet, bis er sie schließt. Ein interaktiver Client ist definiert als
Client, der die @code{CLIENT_INTERACTIVE}-Option für
@code{mysql_real_connect()} benutzt. Siehe auch @code{wait_timeout}.

@item @code{join_buffer_size}
Die Größe des Puffers, der für volle Joins benutzt wird (Joins, die keine
Indexe benutzen). Der Puffer wird einmal pro vollem Join zwischen zwei
Tabellen zugewiesen. Setzen Sie diesen Wert herauf, um einen schnelleren
vollen Join zu erhalten, wenn das Addieren von Indexen nicht möglich ist.
(Normalerweise ist die beste Art, schnelle Joins zu erhalten, das Addieren
von Indexen.)

@c Make texi2html Support index @anchor{Index cache size}. Then change
@c some xrefs to point here
@cindex Indexe, Blockgröße
@item @code{key_buffer_size}
Index-Blöcke werden gepuffert und von allen Threads geteilt.
@code{key_buffer_size} ist die Größe des Puffers, der für Index-Blöcke
benutzt wird.

Setzen Sie diesen Wert herauf, um eine bessere Index-Handhabung zu erzielen
(für alle Lesevorgänge und für mehrfache Schreibvorgänge), so weit, wie Sie
es sich leisten können; 64 MB auf einer 256-MB-Maschine, auf der
hauptsächlich MySQL läuft, ist ein gebräuchlicher Wert. Wenn Sie diesen
Wert allerdings zu hoch setzen (mehr als 50% Ihres gesamten
Arbeitsspeichers), kann es sein, dass Ihr System anfängt auszulagern
(Paging), was SEHR langsam werden kann. Denken Sie daran, dass Sie Platzt
für den Dateisystem-Cache des Betriebssystems lassen müssen, weil MySQL
Daten-Lesen nicht cachet.

Sie können die Performance des Schlüsselpuffers mit @code{show status}
überprüfen und sich die Variablen @code{Key_read_requests},
@code{Key_reads}, @code{Key_write_requests} und @code{Key_writes} ansehen.
Das Verhältnis @code{Key_reads/Key_read_request} sollte normalerweise <
0,01 sein. @code{Key_write/Key_write_requests} ist üblicherweise nahe 1,
wenn Sie hauptsächlich Aktualisieren (Update) und Löschen (Delete)
ausführen, kann aber sehr viel kleiner werden, wenn Sie tendenziell
Aktualisierungen ausführen, die viele Zeilen gleichzeitig betreffen, oder
wenn Sie @code{delay_key_write} benutzen. @xref{SHOW}.

Um noch mehr Geschwindigkeit beim Schreiben vieler Zeilen auf einmal zu
erhalten, benutzen Sie @code{LOCK TABLES}. @xref{LOCK TABLES, , @code{LOCK TABLES}}.

@item @code{language}
Die Sprache, in der Fehlermeldungen ausgegeben werden.

@item @code{large_file_support}
Ob @code{mysqld} mit Optionen für die Unterstützung großer Dateien
kompiliert wurde.

@item @code{locked_in_memory}
Ob @code{mysqld} mit @code{--memlock} in den Speicher gesperrt wurde.

@item @code{log}
Ob das Loggen aller Anfragen angeschaltet ist.

@item @code{log_update}
Ob das Update-Log angeschaltet ist.

@item @code{log_bin}
Ob das Binär-Log angeschaltet ist.

@item @code{log_slave_updates}
Ob Aktualisierungen vom Slave geloggt werden sollen.

@item @code{long_query_time}
Wenn eine Anfrage länger als diesen Wert (in Sekunden) benötigt, wird der
@code{Slow_queries}-Zähler hoch gezählt. Wenn Sie @code{--log-slow-queries}
benutzen, wird die Anfrage in die Slow-Query-Logdatei geschrieben.
@xref{Slow query log}.

@item @code{lower_case_table_names}
Wenn auf 1 gesetzt, werden Tabellennamen in Kleinschreibung auf Platte
gespeichert. Tabellennamen sind dann unabhängig von der verwendeten
Groß-/Kleinschreibung.
@xref{Case sensitivity}.

@item @code{max_allowed_packet}
Die maximale Größe eine Pakets. Der Nachrichtenpuffer wird auf
@code{net_buffer_length} Bytes Länge initialisiert, kann aber wenn nötig
bis zu @code{max_allowed_packet} Bytes Groß werden. Der Vorgabewert ist
klein, um große (möglicherweise falsche) Pakete abzufangen. Sie müssen
diesen Wert erhöhen, wenn Sie große @code{BLOB}-Spalten verwenden. Er
sollte so Groß sein wie die größte @code{BLOB}-Spalte, die Sie verwenden
wollen. Das aktuelle Protokoll begrenzt @code{max_allowed_packet} auf 16 MB.

@item @code{max_binlog_cache_size}
Wenn eine Transaktion aus mehreren Statements mehr als diese Speichermenge
benötigt, erhält man den Fehler "Multi-Statement transaction required more
than 'max_binlog_cache_size' bytes of storage".

@item @code{max_binlog_size}
Verfügbar nach Version 3.23.33. Wenn ein Schreibvorgang ins binäre
(Replikations-) Log den angegebenen Wert übersteigt, werden die Logs
rotiert. Sie können den Wert auf weniger als 1024 Bytes setzen oder auf
mehr als 1 GB. Vorgabe ist 1 GB.

@item @code{max_connections}
Die Anzahl von Clients, die gleichzeitig verbunden sind. Wenn Sie diesen
Wert hoch setzen, wird die Anzahl der Datei-Deskriptoren heraufgesetzt, die
@code{mysqld} benötigt. Siehe weiter unten, Bemerkungen zu Beschränkungen
bei Datei-Deskriptoren. @xref{Too many connections}.

@item @code{max_connect_errors}
Wenn es mehr als diese Anzahl unterbrochener Verbindungen von einem Host
gibt, wird dieser Host von weiteren Verbindungen abgeschnitten. Sie können
diese Sperre mit dem @code{FLUSH HOSTS}-Befehl aufheben.

@item @code{max_delayed_Threads}
Nicht mehr als diese Anzahl von Threads zulassen, um @code{INSERT
DELAYED}-Statements abzuarbeiten. Wenn Sie versuchen, Daten in eine neue
Tabelle einzufügen, wenn alle @code{INSERT DELAYED}-Threads in Benutzung
sind, wird die Zeile eingefügt, als ob das @code{DELAYED}-Attribut nicht
angegeben wäre.

@item @code{max_heap_table_size}
Kein Erzeugen von Heap-Tabellen zulassen, die größer als dieser Wert sind.

@item @code{max_join_size}
Joins, die wahrscheinlich mehr als @code{max_join_size} Datensätze lesen
werden, geben einen Fehler zurück. Setzen Sie diesen Wert, wenn Ihre
Benutzer dazu neigen, Joins auszuführen, denen eine @code{WHERE}-Klausel
fehlt und die daher lange Zeit benötigen und womöglich Millionen von Zeilen
zurück geben.

@item @code{max_sort_length}
Die Anzahl von Bytes, die beim Sortieren von @code{BLOB}- oder
@code{TEXT}-Werten benutzt werden (nur die ersten @code{max_sort_length}
Bytes jedes Werts werden benutzt, der Rest wird ignoriert).

@item @code{max_user_connections}
Die maximale Anzahl aktiver Verbindungen für einen einzelnen Benutzer (0 =
keine Beschränkung).

@item @code{max_tmp_tables}
(Diese Option macht bislang noch nichts.)
Maximale Anzahl von temporären Tabellen, die ein Client zur selben Zeit
offen halten darf.

@item @code{max_write_lock_count}
Nach dieser Anzahl Schreibsperren wird einigen Lesesperren erlaubt,
zwischendurch zu laufen.

@item @code{myisam_recover_options}
Der Wert der @code{--myisam-recover}-Option.

@item @code{myisam_sort_buffer_size}
Der Puffer, der beim Sortieren des Indexes zugewiesen wird, wenn man ein
@code{REPAIR} oder ausführt oder Indexe mit @code{CREATE INDEX} oder
@code{ALTER TABLE} erzeugt.

@item @code{myisam_max_extra_sort_file_size}.
Wenn das Erzeugen der temporären Datei für schnelle Index-Erzeugung um
diesen Wert größer sein würde als die Benutzung des Schlüssel-Caches, wird
die Schlüssel-Cache-Methode bevorzugt. Wird hauptsächlich benutzt, um lange
Zeichen-Schlüssel in großen Tabellen zu zwingen, die langsamere
Schlüssel-Cache-Methode zu benutzen, um den Index zu erzeugen.
@strong{HINWEIS:} Dieser Parameter wird in Megabytes angegeben!

@item @code{myisam_max_sort_file_size}
Die maximale Größe der temporären Datei, die MySQL benutzen darf, während
es den Index erzeugt (während @code{REPAIR}, @code{ALTER TABLE} oder
@code{LOAD DATA INFILE}). Wenn die Datei größer als dieser Wert würde, wird
der Index über den Schlüssel-Cache erzeugt (was langsamer ist).
@strong{HINWEIS:} Dieser Parameter wird in Megabytes angegeben!

@item @code{net_buffer_length}
Der Kommunikationspuffer wird zwischen Anfragen auf diesen Wert zurück
gesetzt. Normalerweise sollte das nicht geändert werden, aber wenn Sie sehr
wenig Arbeitsspeicher haben, können Sie ihn auf die erwartete Größe einer
Anfrage setzen (also die erwartete Länge von SQL-Statements, die von
Clients gesendet werden. Wenn Statements diese Länge überschreiten, wird
der Puffer automatisch vergrößert, bis zu @code{max_allowed_packet} Bytes.)

@item @code{net_read_timeout}
Anzahl von Sekunden, die auf weitere Daten von einer Verbindung gewartet
wird, bevor das Lesen abgebrochen wird. Beachten Sie: Wenn keine Daten von
einer Verbindung erwartet werden, ist der Timeout durch
@code{write_timeout} definiert. Siehe auch @code{slave_read_timeout}.

@item @code{net_retry_count}
Wenn ein Lesevorgang auf einem Kommunikations-Port unterbrochen wird, wird
so oft wie angegeben neu versucht, bevor aufgegeben wird. Dieser Wert
sollte auf @code{FreeBSD} recht hoch sein, weil interne
Unterbrechnungsanforderungen (Interrupts) an alle Threads gesendet werden.

@item @code{net_write_timeout}
Anzahl von Sekunden, die auf das Schreiben eines Blocks zu einer Verbindung
gewartet wird, bis das Schreiben abgebrochen wird.

@item @code{open_files_limit}
Wenn dieser Wert ungleich 0 ist, benutzt @code{mysqld} Datei-Deskriptoren,
die mit @code{setrlimit()} benutzt werden. Wenn dieser Wert gleich 0 ist,
reserviert @code{mysqld} @code{max_connections * 5} oder
@code{max_connections + table_cache * 2} (je nachdem, was größer ist)
Anzahl von Dateien. Sie sollten diesen Wert herauf setzen, wenn
@code{mysqld} Ihnen die Fehlermeldung 'Too many open files' gibt.

@item @code{pid_file}
Der Wert der @code{--pid-file}-Option.

@item @code{port}
Der Wert der @code{--port}-Option.

@item @code{protocol_version}
Die Protokoll-Version, die vom MySQL-Server benutzt wird.

@item @code{record_buffer}
Jeder Thread, der einen sequentiellen Scan ausführt, alloziert einen Puffer
dieser Größe für jede Tabelle, die er scannt. Wenn Sie viele sequentielle
Scans ausführen, sollten Sie diesen Wert herauf setzen.

@item @code{record_rnd_buffer}
Wenn Zeilen nach einem Sortiervorgang in sortierter Reihenfolge gelesen
werden, werden die Zeilen aus diesem Puffer gelesen, um Suchvorgänge auf
der Platte zu vermeiden. Wenn dieser Wert nicht gesetzt ist, wird er auf
den Wert von @code{record_buffer} gesetzt.

@item @code{query_buffer_size}
Die anfängliche Zuweisung des Anfragen-Puffers. Wenn die meisten Ihrer
Anfragen lang sind (zum Beispiel beim Einfügen von Blobs), sollten Sie
diesen Wert herauf setzen!

@item @code{safe_show_databases}
Keine Datenbanken zeigen, wenn der Benutzer keinerlei Datenbank- oder
Tabellen-Berechtigungen dafür hat. Das kann die Sicherheit erhöhen, wenn
Sie sich Sorgen machen, dass Leute in der Lage sind zu sehen, welche
Datenbanken andere Benutzer haben. Siehe auch
@code{skip_show_databases}.

@item @code{server_id}
Der Wert der @code{--server-id}-Option.

@item @code{skip_locking}
Ist @code{OFF}, wenn @code{mysqld} externes Sperren benutzt.

@item @code{skip_networking}
Ist @code{ON}, wenn nur lokale (Socket-) Verbindungen zugelassen sind.

@item @code{skip_show_databases}
Hält Leute davon ab, @code{SHOW DATABASES} zu benutzen, wenn sie keine
the @code{PROCESS_PRIV}-Berechtigung haben. Das kann die Sicherheit erhöhen, wenn
Sie sich Sorgen machen, dass Leute in der Lage sind zu sehen, welche
Datenbanken andere Benutzer haben. Siehe auch @code{safe_show_databases}.

@item @code{slave_read_timeout}
Anzahl von Sekunden, die auf weitere Daten von einer
Master-/Slave-Verbindung gewartet wird, bevor das Lesen abgebrochen wird.

@item @code{slow_launch_time}
Wenn das Erzeugen des Threads länger als dieser Wert (in Sekunden) dauert,
word der @code{Slow_launch_threads}-Zähler herauf gezählt.

@item @code{socket}
Der Unix-Socket, der vom Server benutzt wird.

@item @code{sort_buffer}
Jeder Thread, der einen Sortierdurchgang durchführen muss, alloziert einen
Puffer dieser Größe. Setzen Sie diesen Wert herauf, um schnellere
@code{ORDER BY}- oder @code{GROUP BY}-Operationen zu erhalten.
@xref{Temporary files}.

@item @code{table_cache}
Die Anzahl offener Tabellen für alle Threads. Wenn dieser Wert herauf
gesetzt wird, erhöht sich die Anzahl von Datei-Deskriptoren, die
@code{mysqld} benötigt. Sie können prüfen, ob Sie den Tabellen-Cache
vergrößern müssen, indem Sie die @code{Opened_tables}-Variable prüfen.
@xref{SHOW}. Wenn diese Variable sehr Groß ist und Sie @code{FLUSH TABLES}
nicht oft brauchen (was lediglich alle Tabellen zwingt, geschlossen und
wieder geöffnet zu werden), sollten Sie den Wert dieser Variablen herauf
setzen.

Wegen weiterer Informationen zum Tabellen-Cache sehen Sie unter
@ref{Open tables} nach.

@item @code{table_type}
Der vorgabemäßige Tabellentyp.

@item @code{thread_cache_size}
Wie viele Threads in einem Cache für weitere Benutzung offen gehalten
werden sollen. Wenn eine Client die Verbindung schließt, werden die
Threads des Clients in den Cache geschrieben, wenn es nicht mehr als
@code{Thread_cache_size} Threads als vorher gibt. Alle neuen Threads werden
zuerst aus dem Cache genommen und nur, wenn der Cache leer ist, wird ein
neuer Thread erzeugt. Diese Variable kann hoch gesetzt werden, um die
Performance zu verbessern, wenn Sie sehr viele neue Verbindungen haben.
(Normalerweise führt das nicht zu namhafter Performance-Steigerung, wenn
Sie eine gute Thread-Implementierung haben.) Wie effizient der aktuelle
Thread-Cache für Sie ist, können Sie feststellen, indem Sie den Unterschied
zwischen @code{Connections} und @code{Threads_created} betrachten.

@item @code{thread_concurrency}
On Solaris, @code{mysqld} will call @code{thr_setconcurrency()} mit
this value.  @code{thr_setconcurrency()} permits the Applikation to give
the Threads System a hint für the desired Anzahl von Threads that should
be run at the same time.

@item @code{thread_stack}
Die Stack-Größe jedes Threads. Viele der Beschränkungen, die durch den
@code{crash-me}-Test festgestellt werden, hängen von diesem Wert ab. Der
Vorgabewert ist Groß genug für normale Operationen.
@xref{MySQL Benchmarks}.

@item @code{timezone}
Die Zeitzone für den Server.

@item @code{tmp_table_size}
Wenn eine temporäre Tabelle im Arbeitsspeicher diese Größe überschreitet,
wandelt MySQL sie automatisch in eine @code{MyISAM}-Tabelle auf der Platte
um. Setzen Sie den Wert von @code{tmp_table_size} herauf, wenn Sie viele
fortgeschrittene @code{GROUP BY}-Anfragen und viel Arbeitsspeicher haben.

@item @code{tmpdir}
Das Verzeichnis, das für temporäre Dateien und temporäre Tabellen benutzt
wird.

@item @code{version}
Die Versionsnummer des Servers.

@item @code{wait_timeout}
Die Anzahl von Sekunden, die der Server auf Aktivität auf einer Verbindung
wartet, bevor er sie schließt. Siehe auch @code{interactive_timeout}.
@end table

Der Handbuchabschnitt, der das Tunen von MySQL beschreibt, enthält einige
Informationen darüber, wie die oben aufgeführten Variablen getunt werden.
@xref{Server parameters}.


@node SHOW LOGS, SHOW PROCESSLIST, SHOW VARIABLES, SHOW
@c German node SHOW LOGS
@subsubsection @code{SHOW LOGS}

@code{SHOW LOGS} zeigt Ihnen Statusinformationen über bestehende
Log-Dateien. Momentan werden nur Informationen über Berkeley-DB-Log-Dateien
angezeigt.

@itemize @bullet
@item @code{File} zeigt den vollen Pfad zur Log-Datei.
@item @code{Type} zeigt den Typ der Log-Datei (@code{BDB} für
Berkeley-DB-Log-Dateien).
@item @code{Status} zeigt den Status der Log-Datei (@code{FREE}, wenn die
Datei entfernt werden kann, oder @code{IN USE}, wenn die Datei vom
Transaktions-Subsystem benötigt wird)
@end itemize


@node SHOW PROCESSLIST, SHOW GRANTS, SHOW LOGS, SHOW
@c German node SHOW PROCESSLIST
@subsubsection @code{SHOW PROCESSLIST}

@findex Threads
@findex PROCESSLIST

@cindex Threads, anzeigen
@cindex Prozesse, anzeigen

@code{SHOW PROCESSLIST} zeigt, welche Threads laufen. Diese Information
erhalten Sie auch mit dem @code{mysqladmin processlist}-Befehl. Wenn Sie
die @strong{process}-Berechtigung haben, können Sie alle Threads sehen.
Ansonsten sehen Sie nur Ihre eigenen Threads. @xref{KILL, , @code{KILL}}.
Wenn Sie die @code{FULL}-Option nicht benutzen, werden nur die ersten 100
Zeichen jeder Anfrage gezeigt.

Dieser Befehl ist sehr nützlich, wenn Sie die 'too many
connections'-Fehlermeldung erhalten und herausfinden wollen, was vor sich
geht. MySQL reserviert eine zusätzliche Verbindung für einen Client mit der
@code{Process_priv}-Berechtigung, um sicherzustellen, dass Sie sich
jederzeit einloggen und das System prüfen können (unter der Annahme, dass
Sie diese Berechtigung nicht allen Ihren Benutzern geben).


@node SHOW GRANTS, SHOW CREATE TABLE, SHOW PROCESSLIST, SHOW
@c German node SHOW GRANTS
@subsubsection @code{SHOW GRANTS}

@cindex Berechtigungen, anzeigen

@code{SHOW GRANTS FOR benutzer} listet die @code{Grant}-Befehle auf, die
abgesetzt werden müssen, um die Berechtigungen für einen Benutzer zu
duplizieren. Beispiel:

@example
mysql> SHOW GRANTS FOR root@@localhost;
+----------------------------------------------------------------------+
| Grants for root@@localhost                                           |
+----------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root'@@'localhost' WITH GRANT OPTION |
+----------------------------------------------------------------------+
@end example


@node SHOW CREATE TABLE,  , SHOW GRANTS, SHOW
@c German node SHOW CREATE TABLE
@subsubsection @code{SHOW CREATE TABLE}

Zeigt ein @code{CREATE TABLE}-Statement an, das die angegebene Tabelle
erzeugt:

@example
mysql> show create table tabelle\G
*************************** 1. row ***************************
       Table: tabelle
Create Table: CREATE TABLE tabelle (
  id int(11) default NULL auto_increment,
  s char(60) default NULL,
  PRIMARY KEY (id)
) TYPE=MyISAM

@end example

@code{SHOW CREATE TABLE} setzt Tabellen- und Spaltennamen gemäß der
@code{SQL_QUOTE_SHOW_CREATE}-Option in Anführungszeichen.
@ref{SET OPTION, , @code{SET OPTION SQL_QUOTE_SHOW_CREATE}}.


@node Localisation, Server-Side Scripts, Database Administration, MySQL Database Administration
@c German node Lokalisierung
@section MySQL-Lokalisierung und internationaler Gebrauch



@menu
* Character sets::              
* Languages::                   
* Adding character set::        
* Character arrays::            
* String collating::            
* Multi-byte characters::       
* Problems with character sets::  
@end menu

@node Character sets, Languages, Localisation, Localisation
@c German node Zeichensätze
@subsection Der für Daten und Sortieren benutzte Zeichensatz

@cindex Zeichensätze
@cindex Daten, Zeichensätze
@cindex sortieren, Zeichensätze

Vorgabemäßig benutzt MySQL den ISO-8859-1-(Latin1)-Zeichensatz, wobei nach
schwedischer / finnischer Reihenfolge sortiert wird. Dieser Zeichensatz ist
für die USA und Westeuropa geeignet.

Alle standardmäßigen MySQL-Binärdistributionen werden mit
@code{--with-extra-charsets=complex} kompiliert. Das fügt allen
Standard-Programmen Code hinzu, damit diese @code{latin1} und alle
Multi-Byte-Zeichensätze in der Binärdatei handhaben können. Andere
Zeichensätze werden bei Bedarf aus einer Zeichensatz-Definitionsdatei
geladen.

Der Zeichensatz legt fest, welche Zeichen in Namen erlaubt sind und wie
Dinge durch die @code{ORDER BY}- und @code{GROUP BY}-Klauseln des
@code{SELECT}-Statements sortiert werden.

Sie können den Zeichensatz mit der @code{--default-character-set}-Option
ändern, wenn Sie den Server starten. Die verfügbaren Zeichensätze hängen
von den @code{--with-charset=charset}- und @code{--with-extra-charset=
list-of-charset | complex | all}-Optionen für @code{configure} ab und den
Zeichensatz-Konfigurationsdateien, die in @file{SHAREDIR/charsets/Index}
aufgeführt sind. @xref{configure options}.

Wenn Sie den Zeichensatz ändern, wenn Sie MySQL laufen lassen (was
eventuell auch die Sortierreihenfolge ändert), müssen Sie @code{myisamchk
-r -q} über alle Tabellen laufen lassen. Ansonsten sind Ihre Indexe
eventuell nicht richtig sortiert.

Wenn sich ein Client mit dem MySQL-Server verbindet, schickt der Server den
vorgabemäßigen Zeichensatz, der in Benutzung ist, an den Client. Der
Client schaltet für diese Verbindung auf den Gebrauch dieses Zeichensatzes
um.

Man sollte bei einer SQL-Anfrage @code{mysql_real_escape_string()}
benutzen, wenn man Zeichenketten escapet. @code{mysql_real_escape_string()}
ist identisch mit der alten @code{mysql_escape_string()}-Funktion, ausser
dass es die MySQL-Connection-Handle als ersten Parameter nimmt.

Wenn der Client mit anderen Pfaden kompiliert wird, als wo der Server
installiert ist, und der Benutzer, der MySQL konfigurierte, nicht alle
Zeichensätze in die MySQL-Binärdatei eingeschlossen hat, muss man für den
Client festlegen, wo dieser die zusätzlichen Zeichensätze finden kann, die
er benötigt, falls der Server mit einem anderen Zeichensatz läuft als der
Client.

Das kann man in einer MySQL-Optionsdatei festlegen:

@example
[client]
character-sets-dir=/usr/local/mysql/share/mysql/charsets
@end example

Wobei der Pfad auf das Verzeichnis zeigt, in dem sich die dynamischen
MySQL-Zeichensätze befinden.

Man kann den Client zwingen, einen bestimmten Zeichensatz zu benutzen,
indem man angibt:

@example
[client]
default-character-set=character-set-name
@end example

Aber normalerweise wird das nie benötigt.


@menu
* German character set::        
@end menu

@node German character set,  , Character sets, Character sets
@c German node Deutscher Zeichensatz
@subsubsection Deutscher Zeichensatz

Um eine deutsche Sortierreihenfolge zu erhalten, startet man @code{mysqld}
mit @code{--default-character-set=latin_de}. Das ergibt die folgenden
Kennzeichen:

Beim Sortieren und Vergleichen von Zeichenketten wird das folgende Mapping
auf die Zeichenketten durchgeführt, bevor der Vergleich ausgeführt wird:

@example
ä  ->  ae
ö  ->  oe
ü  ->  ue
ß  ->  ss
@end example

Alle Akzentzeichen werden in ihr Nicht-Akzent-Pendant in Großschreibung
umgewandelt. Alle Buchstaben werden in Großschreibung umgewandelt.

Beim Zeichenkettenvergleich mit @code{LIKE} wird das Mapping von einem auf
zwei Buchstaben nicht durchgeführt. Alle Buchstaben werden in
Großschreibung umgewandelt. Akzente werden aus allen Buchstaben entfernt,
mit folgenden Ausnahmen: @code{Ü}, @code{ü}, @code{Ö}, @code{ö}, @code{Ä}
und @code{ä}.


@node Languages, Adding character set, Character sets, Localisation
@c German node Sprachen
@subsection Nicht englische Fehlermeldungen

@cindex Fehlermeldungen, Sprachen
@cindex Meldungen, Sprachen
@cindex Dateien, Fehlermeldungen
@cindex Sprachunterstützung

@code{mysqld} kann Fehlermeldungen in folgenden Sprachen ausgeben:
tschechisch, dänisch, niederländisch, englisch (die Vorgabe), estnisch,
französisch, deutsch, griechisch, ungarisch, italienisch, japanisch,
koreanisch, norwegisch, norwegisch-ny, polnisch, portugiesisch, rumänisch,
russisch, slowakisch, spanisch und schwedisch.

Um @code{mysqld} mit einer bestimmten Sprache zu starten, benutzen Sie die
@code{--language=sprache} oder @code{-L sprache}-Optionen. Beispiel:

@example
shell> mysqld --language=german
@end example

oder:

@example
shell> mysqld --language=/usr/local/share/german
@end example

Beachten Sie, dass alle Sprachnamen in Kleinschreibung angegeben werden.

Die Sprachdateien liegen (vorgabemäßig) in
@file{@var{mysql_base_dir}/share/@var{language}/}.

Um die Fehlermeldungsdatei zu aktualisieren, editieren Sie die
@file{errmsg.txt}-Datei und führen folgenden Befehl aus, um die
@file{errmsg.sys}-Datei zu erzeugen:

@example
shell> comp_err errmsg.txt errmsg.sys
@end example

Wenn Sie auf eine neuere Version von MySQL aktualisieren, denken Sie daran,
Ihre Änderungen mit der neuen @file{errmsg.txt}-Datei zu wiederholen!


@node Adding character set, Character arrays, Languages, Localisation
@c German node Zeichensatz hinzufügen
@subsection Einen neuen Zeichensatz hinzufügen

@cindex Zeichensätze, hinzufügen
@cindex hinzufügen, Zeichensätze

Um MySQL einen weiteren Zeichensatz hinzuzufügen, führen Sie folgende
Prozedur durch:

Entscheiden Sie, ob der Zeichensatz einfach oder komplex ist. Wenn der
Zeichensatz keine besonderen Zeichenkettenvergleichsroutinen zum Sortieren
und keine Multi-Byte-Unterstützung benötigt, ist er einfach. Wenn er eines
oder beide Features benötigt, ist er komplex.

@code{latin1} und @code{dänisch} zum Beispiel sind einfache Zeichensätze,
wohingegen @code{big5} oder @code{tschechisch} komplexe Zeichensätze sind.

Im folgenden Abschnitt wird angenommen, dass Sie Ihren Zeichensatz
@code{MEINSET} nennen.

Bei einem einfachen Zeichensatz machen Sie folgendes:

@enumerate
@item
Fügen Sie MEINSET am Ende der @file{sql/share/charsets/Index}-Datei hinzu.
Geben Sie ihm eine eindeutige Nummer.

@item
Erzeugen Sie die Datei @file{sql/share/charsets/MEINSET.conf}.
(Sie können hierfür als Grundlage @file{sql/share/charsets/latin1.conf}
benutzen).

Die Syntax für die Datei ist sehr einfach:

@itemize @bullet
@item
Kommentare fangen mit einem '#'-Zeichen an und gehen bis zum Ende der
Zeile.
@item
Wörter werden durch beliebige Mengen von Leerraum getrennt.
@item
Bei der Definition des Zeichensatzes muss jedes Wort eine Zahl im
hexadezimalen Format sein.
@item
Das @code{ctype}-Array nimmt bis zu 257 Wörter auf. Die @code{to_lower}-,
@code{to_upper}- und @code{sort_order}-Arrays nehmen danach jeweils bis zu
256 Wörter auf.
@end itemize

@xref{Character arrays}.

@item
Fügen Sie den Zeichensatznamen den @code{CHARSETS_AVAILABLE}- und
@code{COMPILED_CHARSETS}-Listen in @code{configure.in} hinzu.

@item
Rekonfigurieren, rekompilieren und testen Sie.

@end enumerate

Bei einem komplexen Zeichensatz machen Sie folgendes:

@enumerate
@item
Erzeugen Sie die Datei @file{strings/ctype-MEINSET.c} in der
MySQL-Quelldistribution.

@item
Fügen Sie MEINSET am Ende der @file{sql/share/charsets/Index}-Datei hinzu.
Weisen Sie ihm eine eindeutige Nummer zu.

@item
Sehen Sie sich eine der bestehenden @file{ctype-*.c}-Dateien an, um zu
sehen, was definiert werden muss, zum  Beispiel
@file{strings/ctype-big5.c}. Beachten Sie, dass die Arrays in Ihrer Datei
Namen wie @code{ctype_MEINSET}, @code{to_lower_MEINSET} usw. haben müssen.
Das entspricht den Arrays im einfachen Zeichensatz.
@xref{Character arrays}. Bei einem komplexen Zeichensatz

@item
fügen Sie am Anfang der Datei einen speziellen Kommentar wie folgt ein:

@example
/*
 * Dieser Kommentar wird von configure geparst, um ctype.c zu erzeugen,
 * also ändern Sie ihn nicht, wenn Sie nicht genau wissen, was Sie tun.
 *
 * .configure. number_MEINSET=MYNUMBER
 * .configure. strxfrm_multiply_MEINSET=N
 * .configure. mbmaxlen_MEINSET=N
 */
@end example

Das @code{configure}-Programm benutzt diesen Kommentar, um den Zeichensatz
automatisch in die MySQL-Bibliothek einzufügen.

Die Zeilen mit strxfrm_multiply und mbmaxlen werden in den folgenden
Abschnitten erläutert. Geben Sie diese nur dann ein, wenn Sie die
Zeichenketten-Vergleichsfunktionen oder die
Multi-Byte-Zeichensatzfunktionen benötigen.

@item
Danach sollten Sie einige der folgenden Funktionen erzeugen:

@itemize @bullet
@item @code{my_strncoll_MEINSET()}
@item @code{my_strcoll_MEINSET()}
@item @code{my_strxfrm_MEINSET()}
@item @code{my_like_range_MEINSET()}
@end itemize

@xref{String collating}.

@item
Fügen Sie den Zeichensatznamen den @code{CHARSETS_AVAILABLE}- und
@code{COMPILED_CHARSETS}-Listen in @code{configure.in} hinzu.

@item
Rekonfigurieren, rekompilieren und testen Sie.
@end enumerate

Die Datei @file{sql/share/charsets/README} enthält einige weitere
Anweisungen.

Wenn Sie wollen, dass der Zeichensatz in die MySQL-Distribution aufgenommen
wird, senden Sie einen Patch an @email{internals@@lists.mysql.com}.


@node Character arrays, String collating, Adding character set, Localisation
@c German node Zeichen-Arrays
@subsection Die Zeichen-Definitions-Arrays

@code{to_lower[]} und @code{to_upper[]} sind einfache Arrays, die die
Buchstaben in Klein- und Großschreibung enthalten, die jedem Mitglied des
Zeichensatzes entsprechen. Beispiel:

@example
to_lower['A'] enthält 'a'
to_upper['a'] enthält 'A'
@end example

@code{sort_order[]} ist eine Map, die anzeigt, wie Buchstaben für
Vergleichs- und Sortierzwecke geordnet werden sollten. Bei vielen
Zeichensätzen ist das dasselbe wie @code{to_upper[]} (was bedeutet, dass
das Sortieren ohne Berücksichtigung der Groß-/Kleinschreibung erfolgt).
MySQL sortiert Buchstaben auf der Grundlage des Wertes von
@code{sort_order[character]}. Wegen komplizierterer Sortierregeln sehen Sie
die Erörterung zu Zeichenketten-Vergleichen unten an
@xref{String collating}.

@code{ctype[]} ist ein Array von Bit-Werten, mit einem Element pro Zeichen.
(Beachten Sie, dass @code{to_lower[]}, @code{to_upper[]} und
@code{sort_order[]} durch den Buchstabenwert indiziert werden, aber
@code{ctype[]} durch den Buchstabenwert + 1. Das ist aus Gründen der
Abwärtskompatibilität notwendig, um EOF (Dateiende) handhaben zu können.)

Sie finden folgenden Bitmasken-Definitionen in @file{m_ctype.h}:

@example
#define _U      01      /* Großschreibung */
#define _L      02      /* Kleinschreibung */
#define _N      04      /* Numerisch (Ziffer) */
#define _S      010     /* Leerzeichen */
#define _P      020     /* Punkt */
#define _C      040     /* Steuerungszeichen (Control) */
#define _B      0100    /* leer */
#define _X      0200    /* heXadezimale Ziffer */
@end example

Der @code{ctype[]}-Eintrag für jeden Buchstaben sollte die
Vereinigungsmenge der betreffenden Bitmasken-Werte sein, die den Buchstaben
beschreiben. @code{'A'} beispielsweise ist Buchstabe in Großschreibung
(@code{_U}) und gleichzeitig eine hexadezimale Ziffer (@code{_X}), daher
sollte @code{ctype['A'+1]} folgenden Wert erhalten:

@example
_U + _X = 01 + 0200 = 0201
@end example


@node String collating, Multi-byte characters, Character arrays, Localisation
@c German node Zeichenketten-Vergleich
@subsection Unterstützung für Zeichenketten-Vergleich

@cindex Vergleich, Zeichenketten
@cindex Zeichenkettenvergleich

Wenn die Sortierregeln Ihrer Sprache zu komplex sind, um durch die einfache
@code{sort_order[]}-Tabelle gehandhabt zu werden, müssen Sie die
Zeichenketten-Vergleichsfunktionen benutzen.

Zum jetzigen Zeitpunkt ist die beste Dokumentation hierüber die
Zeichensätze, die bereits implementiert sind. Sehen Sie sich als Beispiele
die Zeichensätze big5, tschechisch, gbk, sjis und tis160 an.

Sie müssen den @code{strxfrm_multiply_MEINSET=N}-Wert mit einem speziellen
Kommentar am Anfang der Datei festlegen. @code{N} sollte auf das höchste
Verhältnis gesetzt werden, auf das die Zeichenketten während
@code{my_strxfrm_MEINSET} anwachsen können (es muss eine positive Ganzzahl
sein).


@node Multi-byte characters, Problems with character sets, String collating, Localisation
@c German node Multi-Byte-Zeichen
@subsection Unterstützung für Multi-Byte-Zeichen

@cindex Buchstaben, Multi-Byte
@cindex Multi-Byte-Zeichen

Wenn Sie Unterstützung für einen neuen Zeichensatz hinzufügen wollen, der 
Multi-Byte-Buchstaben enthält, müssen Sie die Multi-Byte-Zeichenfunktionen
benutzen.

Zum jetzigen Zeitpunkt ist die beste Dokumentation hierüber die
Zeichensätze, die bereits implementiert sind. Sehen Sie sich als Beispiele
die Zeichensätze euc_kr, gb2312, gbk, sjis und ujis an. Diese sind in den
@code{ctype-'charset'.c}-Dateien im @file{strings}-Verzeichnis
implementiert.

Sie müssen den @code{mbmaxlen_MEINSET=N}-Wert in einem speziellen Kommentar
am Anfang der Quelldatei angeben. @code{N} sollte auf die Größe in Bytes
des größten Buchstabens im Zeichensatz gesetzt werden.

@node Problems with character sets,  , Multi-byte characters, Localisation
@c German node Probleme mit Zeichensätzen
@subsection Probleme mit Zeichensätzen

Wenn Sie versuchen, einen Zeichensatz zu benutzen, der nicht in Ihre
Binärdatei kompiliert ist, können Sie verschiedene Probleme bekommen:

@itemize @bullet
@item
Ihr Programm hat einen falschen Pfad zum Speicherort der Zeichensätze.
(Vorgabe ist @file{/usr/local/mysql/share/mysql/charsets}). Das kann durch
die Benutzung der @code{--character-sets-dir}-Option für das fragliche
Programm behoben werden.
@item
Der Zeichensatz ist ein Multi-Byte-Zeichensatz, der nicht dynamisch geladen
werden kann. Wenn das der Fall ist, müssen Sie das Programm mit
Unterstützung für diesen Zeichensatz neu kompilieren.
@item
Der Zeichensatz ist ein dynamischer Zeichensatz, aber Sie haben keine
configure-Datei dafür. In diesem Fall müssen Sie die configure-Datei für
den Zeichensatz aus einer neuen MySQL-Distribution installieren.
@item
Ihre @file{Index}-Datei enthält nicht den Namen für den Zeichensatz.

@example
ERROR 1105: File '/usr/local/share/mysql/charsets/?.conf' not found
(Errcode: 2)
@end example

In diesem Fall müssen Sie sich entweder eine neue @code{Index}-Datei holen
oder den Namen jedes fehlenden Zeichensatzes von Hand eintragen.
@end itemize

Bei MyISAM-Tabellen können Sie den Zeichensatznamen und die Anzahl für eine
Tabelle mit @code{myisamchk -dvv tabelle} prüfen.


@node Server-Side Scripts, Client-Side Scripts, Localisation, MySQL Database Administration
@c German node Serverseitige Skripte
@section Serverseitige Skripte und Dienstprogramme für MySQL



@menu
* Server-Side Overview::        
* safe_mysqld::                 
* mysqld_multi::                
* myisampack::                  
* mysqld-max::                  
@end menu

@node Server-Side Overview, safe_mysqld, Server-Side Scripts, Server-Side Scripts
@c German node Überblick über serverseitige Programme
@subsection Überblick über serverseitige Programme und Dienstprogramme

@cindex Umgebungsvariablen
@cindex Programme, Auflistung

Alle MySQL-Clients, die mittels der @code{mysqlclient}-Bibliothek mit dem
Server kommunizieren, benutzen folgenden Umgebungsvariablen:

@tindex @code{MYSQL_UNIX_PORT}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_UNIX_PORT}
@tindex @code{MYSQL_TCP_PORT}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_TCP_PORT}
@tindex @code{MYSQL_PWD}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_PWD}
@tindex @code{MYSQL_DEBUG}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_DEBUG}
@multitable @columnfractions .25 .75
@item @strong{Name} @tab @strong{Beschreibung}
@item @code{MYSQL_UNIX_PORT} @tab Der vorgabemäßige Socket; benutzt für Verbindungen zu @code{localhost}
@item @code{MYSQL_TCP_PORT}  @tab Der vorgabemäßige TCP/IP-Port
@item @code{MYSQL_PWD} @tab Das vorgabemäßige Passwort
@item @code{MYSQL_DEBUG} @tab Debug-Trace-Optionen beim Debuggen
@item @code{TMPDIR} @tab Das Verzeichnis, in dem temporäre Tabellen / Dateien erzeugt werden
@end multitable

Die Benutzung von @code{MYSQL_PWD} ist unsicher.
@xref{Connecting}.

@tindex @code{MYSQL_HISTFILE}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_HISTFILE}
@tindex @code{HOME}-Umgebungsvariable
@tindex Umgebungsvariable, @code{HOME}
@cindex History-Datei
@cindex Kommandozeilen-History
@tindex .mysql-History-Datei
Der @file{mysql}-Client benutzt die Datei, die in der
@code{MYSQL_HISTFILE}-Umgebungsvariablen angegeben ist, um die
Kommandozeilen-History zu speichern. Der Vorgabewert für die History-Datei
ist @file{$HOME/.mysql_history}, wobei @code{$HOME} der Wert der
@code{HOME}-Umgebungsvariablen ist. @xref{Environment variables}.

Alle MySQL-Programme nehmen viele unterschiedliche Optionen auf. Jedes
MySQL-Programm bietet jedoch eine @code{--help}-Option, die Sie benutzen
können, um eine vollständige Beschreibung der unterschiedlichen
Programmoptionen zu erhalten. Probieren Sie zum Beispiel @code{mysql
--help} aus.

Sie können Vorgabeoptionen für alle Standard-Client-Programme mit einer
Optionsdatei überschreiben. @ref{Option files}.

Die unten stehende Liste beschreibt kurz die MySQL-Programme:

@table @code

@cindex @code{myisamchk}
@item myisamchk
Dienstprogramm zur Beschreibung, Prüfung, Optimierung und Reparatur von
MySQL-Tabellen. Weil @code{myisamchk} viele Funktionen hat, ist es in einem
eigenen Kapitel beschrieben. @xref{MySQL Database Administration}.

@cindex @code{make_binary_distribution}
@item make_binary_distribution
Macht ein Binär-Release eines kompilierten MySQL. Dieses könnte über FTP an
@file{/pub/mysql/Incoming} oder an @code{Support.mysql.com} geschickt
werden, damit andere MySQL-Benutzer es benutzen können.

@cindex @code{msql2mysql}
@item msql2mysql
Ein Shell-Skript, das @code{mSQL}-Programme zu MySQL konvertiert. Es deckt
nicht alle Fälle ab, ist aber hilfreich, um mit dem Konvertieren
anzufangen.

@cindex @code{mysqlaccess}
@item mysqlaccess
Ein Skript, das die Zugriffsberechtigungen für eine Host-, Benutzer- und
Datenbank-Kombination prüft.

@cindex @code{mysqladmin}
@item mysqladmin
Dienstprogramm für die Durchführung von Verwaltungsoperationen wie Erzeugen
und Löschen von Datenbanken, Neuladen der Berechtigungstabellen,
Zurückschreiben von Tabellen auf Platte und Neuöffnen von Log-Dateien.
@code{mysqladmin} kann auch benutzt werden, um Versionsnummer sowie Status-
und Prozess-Informationen vom Server zu erhalten.
@xref{mysqladmin, , @code{mysqladmin}}.

@cindex @code{mysqlbug}
@item mysqlbug
Das MySQL-Bug-Bericht-Skript. Dieses Skript sollte immer benutzt werden,
wenn Sie einen Bug-Bericht an die MySQL-Liste ausfüllen.

@cindex @code{mysqld}
@item mysqld
Der SQL-Daemon. Dieser sollte immer laufen.

@cindex @code{mysqldump}
@item mysqldump
Dumpt eine MySQL-Datenbank in eine Datei als SQL-Statements oder als
Tabulator-separierte Textdateien. Verbesserte Freeware, ursprünglich von
Igor Romanenko. @xref{mysqldump, , @code{mysqldump}}.

@cindex @code{mysqlimport}
@item mysqlimport
Importiert Textdateien in die jeweiligen Tabellen mittels @code{LOAD DATA
INFILE}. @xref{mysqlimport, , @code{mysqlimport}}.

@cindex @code{mysqlshow}
@item mysqlshow
Zeigt Informationen über Datenbanken, Tabellen, Spalten und Indexe an.

@cindex @code{mysql_install_db}
@item mysql_install_db
Erzeugt die MySQL-Berechtigungstabellen mit vorgabemäßigen Berechtigungen.
Dieses Skript wird gewöhnlich nur einmal ausgeführt, wenn Sie MySQL das
erste Mal auf einem System installieren.

@cindex @code{replace}
@item replace
Ein Dienstprogramm, das von @code{msql2mysql} benutzt wird, aber auch
darüber hinaus benutzt werden kann. @code{replace} ändert Zeichenketten in
Dateien oder auf der Standardeingabe. Benutzt eine finite Status-Maschine,
um zuerst Übereinstimmung mit längeren Zeichenketten zu finden. Kann
benutzt werden, um Zeichenketten umzudrehen. Der folgende Befehl zum
Beispiel dreht @code{a} und @code{b} in den angegebenen Dateien um:

@example
shell> replace a b b a --Datei1 Datei2 ...
@end example
@end table


@node safe_mysqld, mysqld_multi, Server-Side Overview, Server-Side Scripts
@c German node safe_mysqld
@subsection safe_mysqld, der Wrapper um mysqld

@cindex Werkzeuge, safe_mysqld
@cindex Skripts
@cindex @code{safe_mysqld}

@code{safe_mysqld} ist die empfohlene Art, einen @code{mysqld}-Daemon unter
Unix zu starten. @code{safe_mysqld} fügt einige Sicherheits-Features hinzu
wie das Neustarten des Servers, wenn ein Fehler auftritt, und das
Mitschreiben von Laufzeitinformationen in eine Log-Datei.

Wenn Sie nicht @code{--mysqld=#} oder @code{--mysqld-version=#} benutzen,
benutzt @code{safe_mysqld} eine ausführbare Datei namens @code{mysqld-max},
wenn es diese gibt. Wenn nicht, startet @code{safe_mysqld} @code{mysqld}.
Das macht es sehr einfach, @code{mysqld-max} anstelle von @code{mysqld}
versuchsweise zu benutzen. Kopieren Sie einfach @code{mysqld-max} dorthin,
wo @code{mysqld} liegt, und es wird benutzt werden.

Normalerweise sollte man das @code{safe_mysqld}-Skript nie editieren,
sondern statt dessen die Optionen für @code{safe_mysqld} in den
@code{[safe_mysqld]}-Abschnitt der @code{my.cnf}-Datei einfügen.
@code{safe_mysqld} liest alle Optionen des @code{[mysqld]}-,
@code{[server]}- und @code{[safe_mysqld]}-Abschnitts aus den
Optionsdateien. @xref{Option files}.

Beachten Sie, dass alle Optionen auf der Kommandozeile für
@code{safe_mysqld} an @code{mysqld} durchgereicht werden. Wenn Sie in
@code{safe_mysqld} irgend welche Optionen benutzen wollen, die
@code{mysqld} nicht unterstützt, müssen Sie diese in der Optionsdatei
angeben.

Die meisten Optionen für @code{safe_mysqld} sind dieselben wie die Optionen
für @code{mysqld}. @xref{Command-line options}.

@code{safe_mysqld} unterstützt folgende Optionen:

@table @code
@item --basedir=pfad
@item --core-file-size=#
Größe der Core-Datei, die @code{mysqld} in der Lage sein sollte zu
erzeugen. Wird an @code{ulimit -c} durchgereicht.
@item --datadir=pfad
@item --defaults-extra-file=pfad
@item --defaults-file=pfad
@item --err-log=pfad
@item --ledir=pfad
Pfad zu @code{mysqld}
@item --log=pfad
@item --mysqld=mysqld-version
Name der @code{mysqld}-Version im @code{ledir}-Verzeichnis, die Sie starten
wollen.
@item --mysqld-version=version
Ähnlich wie @code{--mysqld=}, aber hier für nur das Suffix für
@code{mysqld} angegeben. Wenn Sie zum Beispiel @code{--mysqld-version=max}
benutzen,  startet @code{safe_mysqld} die @code{ledir/mysqld-max}-Version.
Wenn das Argument für @code{--mysqld-version} leer ist, wird
@code{ledir/mysqld} benutzt.
@item --no-defaults
@item --open-files-limit=#
Anzahl der Dateien, die @code{mysqld} in der Lage sein sollte zu öffnen.
Wird an @code{ulimit -n} durchgereicht. Beachten Sie, dass Sie
@code{safe_mysqld} als Root starten müssen, damit dies korrekt
funktioniert!
@item --pid-file=pfad
@item --port=#
@item --socket=pfad
@item --timezone=#
Setzt die Zeitzone (die @code{TZ})-Variable auf den Wert dieses Parameters.
@item --user=#
@end table

Das @code{safe_mysqld}-Skript ist so geschrieben, dass es normalerweise
einen Server starten kann, der aus einer Quell- oder einer Binärversion von
MySQL installiert wurde, selbst wenn diese den Server an etwas anderen
Stellen installieren. @code{safe_mysqld} erwartet, dass eine der folgenden
Bedingungen zutrifft:

@itemize @bullet
@item
Server und Datenbanken liegen relativ zum Verzeichnis, aus dem
@code{safe_mysqld} aufgerufen wird. @code{safe_mysqld} sucht unterhalb
seines Arbeitsverzeichnisses nach @file{bin}- und
@file{data}-Verzeichnissen (bei Binärdistributionen) oder nach
@file{libexec}- und @file{var}-Verzeichnissen (bei Quelldistributionen).
Diese Bedingung sollte zutreffen, wenn Sie @code{safe_mysqld} aus Ihrem
MySQL-Installationsverzeichnis ausführen (zum Beispiel
@file{/usr/local/mysql} bei einer Binärdistribution).

@item
Wenn Server und Datenbanken nicht relativ zum Arbeitsverzeichnis liegen,
versucht @code{safe_mysqld}, sie anhand absoluter Pfadnamen zu finden.
Typische Speicherort sind @file{/usr/local/libexec} und
@file{/usr/local/var}. Die tatsächlichen Speicherorte werden festgelegt,
wenn die Distribution gebaut wird, woher @code{safe_mysqld} kommt. Sie
sollten korrekt sein, wenn MySQL an einem Standardort installiert wurde.
@end itemize

Weil @code{safe_mysqld} versucht, Server und Datenbanken relativ zum
eigenen Arbeitsverzeichnis zu finden, können Sie eine Binärdistribution von
MySQL irgendwo hin installieren, so lange Sie @code{safe_mysqld} aus dem
MySQL-Installationsverzeichnis starten:

@example
shell> cd mysql_installations_verzeichnis
shell> bin/safe_mysqld &
@end example

Wenn @code{safe_mysqld} fehlschlägt, selbst wenn es aus dem
MySQL-Installationsverzeichnis aufgerufen wurde, können Sie es so ändern,
dass es den Pfad zu @code{mysqld} und die Pfadnamen-Optionen benutzt, die
auf Ihrem System korrekt sind. Beachten Sie, dass bei zukünftigen
Aktualisierungen von MySQL Ihre veränderte Version von @code{safe_mysqld}
überschrieben wird. Daher sollten Sie eine Kopie Ihrer editierten Version
machen, damit Sie diese neu installieren können.


@node mysqld_multi, myisampack, safe_mysqld, Server-Side Scripts
@c German node mysqld_multi
@subsection mysqld_multi, Programm zur Verwaltung mehrerer MySQL-Server

@cindex Werkzeuge, mysqld_multi
@cindex Skripts
@cindex multi mysqld
@cindex @code{mysqld_multi}

@code{mysqld_multi} ist für die Verwaltung mehrerer @code{mysqld}-Prozesse
gedacht, die auf unterschiedlichen UNIX-Sockets und TCP/IP-Ports laufen.

Das Programm sucht nach Gruppe(n), die [mysqld#] benannt sind, in my.cnf
(oder der angegebenen --config-file=...), wobei # jede positive Zahl ab 1
sein kann. Diese Gruppen sollten dieselben sein wie die übliche
@code{[mysqld]}-Gruppe (zum Beispiel Optionen für mysqld, siehe
ausführliche Informationen im Handbuch über diese Gruppe), aber mit
denjenigen Port-, Socket- usw. Optionen, die für jeden separaten
@code{mysqld}-Prozess gewünscht sind. Die Zahl im Gruppennamen hat eine
andere Funktion: Sie kann benutzt werden, um bestimmte @code{mysqld}-Server
zu starten, anzuhalten, oder Berichte über sie mit diesem Programm
auszugeben. Unten stehen weitere Informationen zur Benutzung und zu den
Optionen.

@example
Benutzung: mysqld_multi [OPTIONS] @{start|stop|report@} [GNR,GNR,GNR...]
oder       mysqld_multi [OPTIONS] @{start|stop|report@} [GNR-GNR,GNR,GNR-GNR,...]
@end example

Die GNR oben bedeutet die Gruppennummer. Sie können jede GNR starten,
anhalten oder Berichtsinformationen über sie ausgeben, oder über mehrere
von ihnen zugleich. (Siehe --example) Die GNRs in der Liste können mit
Komma getrennt oder mit Bindestrich kombiniert werden, wobei letzteres
heißt, dass alle GNRs zwischen GNR1-GNR2 betroffen sind. Ohne GNR-Argument
werden alle gefundenen Gruppen entweder gestartet, angehalten, oder es
werden Berichtsinformationen über sie ausgegeben. Beachten Sie, dass Sie in
der GNR-Liste keinen Leerraum haben dürfen. Alles nach Leerraum wird
ignoriert.

@code{mysqld_multi} unterstützt folgende Optionen:

@table @code
@cindex config-file option
@item --config-file=...
Alternative config-Datei. HINWEIS: Das betrifft nicht die eigenen Optionen
des Programms (Gruppe @code{[mysqld_multi]}), sondern nur die Gruppen
[mysqld#]. Ohne diese Option wird alles aus der normalen my.cnfDatei heraus
gesucht.
@cindex Beispiel option
@item --example
Zeigt ein Beispiel einer config-Datei.
@cindex help option
@item --help
Hilfetext ausgeben und beenden.
@cindex log option
@item --log=...
Log-Datei. Name und voller Pfad zur Log-Datei. HINWEIS: Wenn es die Datei
gibt, wird alles angehängt.
@cindex mysqladmin option
@item --mysqladmin=...
@code{mysqladmin}-Binärdatei, die zum Herunterfahren des Servers benutzt
wird.
@cindex mysqld option
@item --mysqld=...
@code{mysqld}-Binärdatei, die benutzt wird. Beachten Sie, dass Sie auch
@code{safe_mysqld} diese Option angeben können. Die Optionen werden an
@code{mysqld} durchgereicht. Stellen Sie jedoch sicher, dass Sie
@code{mysqld} in Ihrer Umgebungsvariablen @code{PATH} haben oder bearbeiten
Sie @code{safe_mysqld}.
@cindex no-log option
@item --no-log
An stdout ausgeben statt in die Log-Datei. Vorgabemäßig ist die Log-Datei
angeschaltet.
@cindex password option
@item --password=...
Passwort für Benutzer von @code{mysqladmin}.
@cindex tcp-ip option
@item --tcp-ip
Zu MySQL-Server(n) über den TCP/IP-Port statt über den UNIX-Socket
verbinden. Das betrifft das Anhalten und Berichten. Wenn eine Socket-Datei
fehlt, kann der Server trotzdem laufen, aber man kann nur über den
TCP/IP-Port auf ihn zugreifen. Vorgabemäßig wird die Verbindung über den
UNIX-Socket hergestellt.
@cindex user option
@item --user=...
MySQL-Benutzer von @code{mysqladmin}.
@cindex version option
@item --version
Versionsnummer ausgeben und beenden.
@end table

Einige Anmerkungen zu @code{mysqld_multi}:

@itemize @bullet
@item
Stellen Sie sicher, dass der MySQL-Benutzer, der die @code{mysqld}-Dienste
anhält (indem er zum Beispiel @code{mysqladmin} benutzt), dasselbe Passwort
und denselben Benutzernamen für alle Daten-Verzeichnisse benutzt, auf die
zugegriffen wird (zur 'mysql'-Datenbank). Stellen Sie ausserdem sicher,
dass der Benutzer die 'Shutdown_priv'-Berechtigung hat! Wenn Sie viele
Daten-Verzeichnisse und viele verschiedene 'mysql'-Datenbanken mit
unterschiedlichen Passwörtern für den MySQL-'root'-Benutzer haben, sollten
Sie einen allgemeinen 'multi_admin'-Benutzer anlegen, der dasselbe Passwort
benutzt (siehe unten). Hier ein Beispiel dafür:
@example
shell> mysql -u root -S /tmp/mysql.sock -proot_password -e
"GRANT SHUTDOWN ON *.* TO multi_admin@@localhost IDENTIFIED BY 'multipass'"
@xref{Privileges}.
@end example
Das oben Angegebene müssen Sie für jeden laufenden @code{mysqld} im
Daten-Verzeichnis tun, das Sie haben (ändern Sie einfach den Socket,
-S=...).
@item
@code{pid-file} ist sehr wichtig, wenn Sie @code{safe_mysqld} benutzen, um
@code{mysqld} zu starten (zum Beispiel --mysqld=safe_mysqld). Jeder
@code{mysqld} sollte seine eigene @code{pid-file} haben. Der Vorteil der
Benutzung von @code{safe_mysqld} anstelle von @code{mysqld} direkt ist
hierbei, dass @code{safe_mysqld} jeden @code{mysqld}-Prozess 'bewacht' und
neu startet, falls ein @code{mysqld}-Prozess wegen eines Signals kill -9
fehlschlägt oder ähnliches (wenn beispielsweise Speicherzugriffsfehler
auftreten, was bei MySQL natürlich nie passiert ;-). Beachten Sie bitte,
dass es für das @code{safe_mysqld}-Skript eventuell erforderlich ist, es
von einer bestimmten Stelle aus zu starten. Das heißt, dass Sie eventuell
in ein bestimmtes Verzeichnis wechseln müssen, bevor Sie
@code{mysqld_multi} starten. Wenn Sie beim Starten Probleme haben, sehen
Sie bitte im @code{safe_mysqld}-Skript nach. Überprüfen Sie insbesondere
folgende Zeilen:
@example
--------------------------------------------------------------------------
MY_PWD=`pwd` Check if we are starting this relative (for the binary
release) if test -d /data/mysql -a -f ./share/mysql/englisch/errmsg.sys
-a -x ./bin/mysqld
--------------------------------------------------------------------------
@xref{safe_mysqld, , @code{safe_mysqld}}.
@end example
Der obige Test soll erfolgreich verlaufen, ansonsten können Sie Probleme
bekommen.
@item
Vermeiden Sie Gefahren, die auftauchen, wenn Sie mehrere @code{mysqlds} im
selben Daten-Verzeichnis starten. Benutzen Sie unterschiedlichen
Daten-Verzeichnisse, es sei denn, Sie wissen @strong{GENAU}, was Sie tun!
@item
Die Socket-Datei und der TCP/IP-Port müssen für jeden @code{mysqld}
verschieden sein.
@item
Die erste und die fünfte @code{mysqld}-Gruppe wurden beim Beispiel
absichtlich ausgelassen. Sie haben eventuell 'Lücken' in der config-Datei.
Das gibt Ihnen mehr Flexibilität. Die Reihenfolge, in der die
@code{mysqlds} gestartet oder angehalten werden, hängt von der Reihenfolge
ab, in der sie in der config-Datei erscheinen.
@item
Wenn Sie auf eine bestimmte Gruppe verweisen wollen, wenn Sie GNR bei
diesem Programm benutzen, nehmen Sie einfach die Nummer am Ende des
Gruppennamens ( [mysqld# <== ).
@item
Eventuell sollten Sie die Option '--user' für @code{mysqld} benutzen, aber
um das zu tun, müssen Sie root sein, wenn Sie das
@code{mysqld_multi}-Skript starten. Wenn Sie die Option in der config-Datei
haben, macht das nichts; Sie erhalten nur eine Warnmeldung, wenn Sie nicht
der Superuser sind und die @code{mysqlds} unter @strong{IHREM} UNIX-Account
gestartet werden. @strong{WICHTIG}: Stellen Sie sicher, dass die
@code{pid-file} und das Daten-Verzeichnis für @strong{DENJENIGEN}
UNIX-Benutzer lesbar und schreibbar sind (und ausführbar im letzteren
Fall), als der der spezifische @code{mysqld}-Prozess gestartet wird.
Benutzen Sie hier @strong{NICHT} den UNIX-root-Account, es sei denn, Sie
wissen @strong{GENAU}, was Sie tun!
@item
@strong{SEHR WICHTIG}: Stellen Sie sicher, dass Sie die Bedeutung der
Optionen verstehen, die an die @code{mysqlds} durchgereicht werden und
@strong{WARUM} Sie mehrere verschiedene @code{mysqld}-Prozesse haben
wollen. Mehrere @code{mysqlds} in einem Daten-Verzeichnis starten
@strong{ergibt keine zusätzliche Performance} bei einem threaded System!
@end itemize

@xref{Multiple servers}.

Hier ist ein Beispiel einer config-Datei für @code{mysqld_multi}.

@example
# Diese Datei sollte wahrscheinlich in Ihrem Heimatverzeichnis liegen (~/.my.cnf) oder in /etc/my.cnf
# Version 2.1 von Jani Tolonen

[mysqld_multi]
mysqld     = /usr/local/bin/safe_mysqld
mysqladmin = /usr/local/bin/mysqladmin
user       = multi_admin
password   = multipass

[mysqld2]
socket     = /tmp/mysql.sock2
port       = 3307
pid-file   = /usr/local/mysql/var2/hostname.pid2
datadir    = /usr/local/mysql/var2
language   = /usr/local/share/mysql/english
user       = john

[mysqld3]
socket     = /tmp/mysql.sock3
port       = 3308
pid-file   = /usr/local/mysql/var3/hostname.pid3
datadir    = /usr/local/mysql/var3
language   = /usr/local/share/mysql/swedish
user       = monty

[mysqld4]
socket     = /tmp/mysql.sock4
port       = 3309
pid-file   = /usr/local/mysql/var4/hostname.pid4
datadir    = /usr/local/mysql/var4
language   = /usr/local/share/mysql/estonian
user       = tonu

[mysqld6]
socket     = /tmp/mysql.sock6
port       = 3311
pid-file   = /usr/local/mysql/var6/hostname.pid6
datadir    = /usr/local/mysql/var6
language   = /usr/local/share/mysql/japanese
user       = jani
@end example

@xref{Option files}.


@node myisampack, mysqld-max, mysqld_multi, Server-Side Scripts
@c German node myisampack
@subsection myisampack, MySQL-Programm zum Erzeugen komprimierter Nur-Lese-Tabellen

@cindex komprimierte Tabellen
@cindex Tabellen, komprimierte
@cindex MyISAM, komprimierte Tabellen
@cindex @code{myisampack}
@cindex @code{pack_isam}

@code{myisampack} wird benutzt, um MyISAM-Tabellen zu komprimieren.
@code{pack_isam} wird benutzt, um ISAM-Tabellen zu komprimieren. Weil
ISAM-Tabellen veraltet sind, wird hier nur @code{myisampack} erörtert, aber
alles, was auf @code{myisampack} zutrifft, gilt auch für @code{pack_isam}.

@code{myisampack} funktioniert, indem jede Spalte in der Tabelle separat
komprimiert wird. Die Informationen, die benötigt werden, um Spalten zu
dekomprimieren, werden in den Arbeitsspeicher gelesen, wenn die Tabelle
geöffnet wird. Das ergibt viel bessere Performance beim Zugriff auf
einzelne Datensätze, denn man muss nur exakt einen Datensatz
dekomprimieren, nicht einen viel größeren Block, wie das zum Beispiel bei
der Benutzung von Stacker auf MS-DOS nötig ist. Üblicherweise komprimiert
@code{myisampack} die Daten-Datei auf 40%-70%.

MySQL benutzt Speicher-Mapping (@code{mmap()}) auf komprimierte Tabellen
und geht zu normalen Lesen / Schreiben von Dateien zurück, wenn
@code{mmap()} nicht funktioniert.

Für @code{myisampack} gibt es momentan zwei Einschränkungen:
@itemize @bullet
@item
Nach dem Komprimieren ist die Tabelle nur-lesbar.
@item
@code{myisampack} kann auch @code{BLOB}- oder @code{TEXT}-Spalten
komprimieren. Das ältere @code{pack_isam} konnte das nicht.
@end itemize

Die Behebung dieser Einschränkungen steht mit niedrigen Priorität auf
unserer TODO-Liste.

@code{myisampack} wird wie folgt aufgerufen:

@example
shell> myisampack [options] Dateiname ...
@end example

Jeder Dateiname sollte der Name einer Index-(@file{.MYI})-Datei sein. Wenn
Sie nicht im Datenbank-Verzeichnis sind, müssen Sie den Pfadnamen zur Datei
angeben. Die @file{.MYI} Erweiterung kann weggelassen werden.

@code{myisampack} unterstützt folgende Optionen:

@table @code
@item -b, --backup
Stellt eine Datensicherung der Tabelle als @code{tabelle.OLD} her.

@item -#, --debug=debug_options
Debug-Log ausgeben. Die @code{debug_options}-Zeichenkette ist häufig
@code{'d:t:o,filename'}.

@item -f, --force
Erzwingt die Komprimierung der Tabelle, selbst wenn sie dadurch größer
wird oder die temporäre Datei existiert. @code{myisampack} erzeugt eine
temporäre Datei namens @file{tabelle.TMD}, während es die Tabelle
komprimiert. Wenn Sie @code{myisampack} killen, kann es sein, dass die
@file{.TMD}-Datei nicht gelöscht wird. Normalerweise wird @code{myisampack}
mit einer Fehlermeldung beendet, wenn es eine existierende
@file{tabelle.TMD}-Datei findet. Mit @code{--force} packt @code{myisampack}
die Tabelle trotzdem.

@item -?, --help
Hilfetext ausgeben und beenden.

@item -j große_tabelle, --join=große_tabelle
Verbindet alle Tabellen, die auf der Kommandozeile angegeben wurden, in
eine einzige große Tabelle @code{große_tabelle}. Alle Tabellen, die
kombiniert werden sollen, MÜSSEN identisch sein (dieselben Spaltennamen und
-typen, dieselben Indexe usw.).

@item -p #, --packlength=#
Legt die Speichergröße der Datensatzlänge in Bytes fest. Der Wert sollte
1, 2 oder 3 sein. (@code{myisampack} speichert alle Zeilen mit
Längenzeigern von 1, 2, oder 3 Bytes. In den meisten Fällen kann
@code{myisampack} den richtigen Längenwert festlegen, bevor es anfängt, die
Datei zu komprimieren. Während des Komprimierungsprozesses stellt es aber
eventuell fest, dass es eine kürzere Länge hätte nehmen können. In diesem
Fall gibt @code{myisampack} einen Hinweis aus, dass Sie beim nächsten Mal,
wenn Sie dieselbe Datei packen, eine kürzere Datensatzlänge nehmen
sollten.)

@item -s, --silent
Schweigsamer Modus. Ausgaben erfolgen nur, wenn Fehler auftreten.

@item -t, --test
Tabelle nicht tatsächlich komprimieren, sondern nur testweise packen.

@item -T dir_name, --tmp_dir=dir_name
Das genannte Verzeichnis als Speicherort der temporären Tabelle benutzen.

@item -v, --verbose
Geschwätziger Modus. Informationen über den Fortschritt und das
Komprimierungsergebnis ausgeben.

@item -V, --version
Versionsinformationen ausgeben und beenden.

@item -w, --wait
Warten und noch einmal versuchen, wenn die Tabelle in Benutzung ist. Wenn
der @code{mysqld}-Server mit der @code{--skip-locking}-Option aufgerufen
wurde, ist es keine gute Idee, @code{myisampack} aufzurufen, wenn die
Tabelle während des Komprimierungsprozesses möglicherweise aktualisiert
wird.
@end table

@cindex Beispiele, komprimierte Tabellen
Die unten stehende Befehlssequenz zeigt eine typische
Tabellen-Komprimierungssitzung:

@example
shell> ls -l station.*
-rw-rw-r--   1 monty    my         994128 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          53248 Apr 17 19:00 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:   station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-02-02  3:06:43
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafile pointer (bytes):     2  Keyfile pointer (bytes):     2
Max datafile length:   54657023  Max keyfile length:   33554431
Recordlength:               834
Record format: Fixed length

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long              1024       1024          1
2   32    30  multip. text                      10240       1024          1

Field Start Length Type
1     1     1
2     2     4
3     6     4
4     10    1
5     11    20
6     31    1
7     32    30
8     62    35
9     97    35
10    132   35
11    167   4
12    171   16
13    187   35
14    222   4
15    226   16
16    242   20
17    262   20
18    282   20
19    302   30
20    332   4
21    336   4
22    340   1
23    341   8
24    349   8
25    357   8
26    365   2
27    367   2
28    369   4
29    373   4
30    377   1
31    378   2
32    380   8
33    388   4
34    392   4
35    396   4
36    400   4
37    404   1
38    405   4
39    409   4
40    413   4
41    417   4
42    421   4
43    425   4
44    429   20
45    449   30
46    479   1
47    480   1
48    481   79
49    560   79
50    639   79
51    718   79
52    797   8
53    805   1
54    806   1
55    807   20
56    827   4
57    831   4

shell> myisampack station.MYI
Compressing station.MYI: (1192 records)
- Calculating statistics

normal:     20  empty-space:      16  empty-zero:        12  empty-fill:  11
pre-space:   0  end-space:        12  table-lookups:      5  zero:         7
Original trees:  57  After join: 17
- Compressing file
87.14%

shell> ls -l station.*
-rw-rw-r--   1 monty    my         127874 Apr 17 19:00 station.MYD
-rw-rw-r--   1 monty    my          55296 Apr 17 19:04 station.MYI
-rw-rw-r--   1 monty    my           5767 Apr 17 19:00 station.frm

shell> myisamchk -dvv station

MyISAM file:     station
Isam-version:  2
Creation time: 1996-03-13 10:08:58
Recover time:  1997-04-17 19:04:26
Data records:              1192  Deleted blocks:              0
Datafile: Parts:           1192  Deleted data:                0
Datafilepointer (bytes):      3  Keyfile pointer (bytes):     1
Max datafile length:   16777215  Max keyfile length:     131071
Recordlength:               834
Record format: Compressed

table description:
Key Start Len Index   Type                       Root  Blocksize    Rec/key
1   2     4   unique  unsigned long             10240       1024          1
2   32    30  multip. text                      54272       1024          1

Field Start Length Type                         Huff tree  Bits
1     1     1      constant                             1     0
2     2     4      zerofill(1)                          2     9
3     6     4      no zeros, zerofill(1)                2     9
4     10    1                                           3     9
5     11    20     table-lookup                         4     0
6     31    1                                           3     9
7     32    30     no endspace, not_always              5     9
8     62    35     no endspace, not_always, no empty    6     9
9     97    35     no empty                             7     9
10    132   35     no endspace, not_always, no empty    6     9
11    167   4      zerofill(1)                          2     9
12    171   16     no endspace, not_always, no empty    5     9
13    187   35     no endspace, not_always, no empty    6     9
14    222   4      zerofill(1)                          2     9
15    226   16     no endspace, not_always, no empty    5     9
16    242   20     no endspace, not_always              8     9
17    262   20     no endspace, no empty                8     9
18    282   20     no endspace, no empty                5     9
19    302   30     no endspace, no empty                6     9
20    332   4      always zero                          2     9
21    336   4      always zero                          2     9
22    340   1                                           3     9
23    341   8      table-lookup                         9     0
24    349   8      table-lookup                        10     0
25    357   8      always zero                          2     9
26    365   2                                           2     9
27    367   2      no zeros, zerofill(1)                2     9
28    369   4      no zeros, zerofill(1)                2     9
29    373   4      table-lookup                        11     0
30    377   1                                           3     9
31    378   2      no zeros, zerofill(1)                2     9
32    380   8      no zeros                             2     9
33    388   4      always zero                          2     9
34    392   4      table-lookup                        12     0
35    396   4      no zeros, zerofill(1)               13     9
36    400   4      no zeros, zerofill(1)                2     9
37    404   1                                           2     9
38    405   4      no zeros                             2     9
39    409   4      always zero                          2     9
40    413   4      no zeros                             2     9
41    417   4      always zero                          2     9
42    421   4      no zeros                             2     9
43    425   4      always zero                          2     9
44    429   20     no empty                             3     9
45    449   30     no empty                             3     9
46    479   1                                          14     4
47    480   1                                          14     4
48    481   79     no endspace, no empty               15     9
49    560   79     no empty                             2     9
50    639   79     no empty                             2     9
51    718   79     no endspace                         16     9
52    797   8      no empty                             2     9
53    805   1                                          17     1
54    806   1                                           3     9
55    807   20     no empty                             3     9
56    827   4      no zeros, zerofill(2)                2     9
57    831   4      no zeros, zerofill(1)                2     9
@end example

Die Informationen, die @code{myisampack} ausgibt, sind unten beschrieben:

@table @code
@item normal
Die Anzahl von Spalten, für die keine spezielle Komprimierung benutzt wird.

@item empty-space
Die Anzahl von Spalten, die Werte enthalten, die ausschließlich aus
Leerzeichen bestehen. Diese Werte nehmen 1 Bit in Anspruch.

@item empty-zero
Die Anzahl von Spalten, die Werte enthalten, die nur aus binären Nullen
bestehen. Diese Werte nehmen 1 Bit in Anspruch.

@item empty-fill
Die Anzahl von Ganzzahl-Spalten, die nicht den gesamten Bereich Ihres Typs
einnehmen. Diese werden auf einen kleineren Typ geändert (eine
@code{INTEGER}-Spalte kann zum Beispiel auf @code{MEDIUMINT} geändert
werden).

@item pre-space
Die Anzahl von Dezimal-Spalten, die mit führenden Leerzeichen gespeichert
sind. In diesem Fall enthält jeder Wert einen Zähler für die Anzahl
führender Leerzeichen.

@item end-space
Die Anzahl von Spalten, die viele Leerzeichen am Ende enthalten. In diesem
Fall enthält jeder Wert einen Zähler für die Anzahl von Leerzeichen am
Ende.

@item table-lookup
Die Spalte hat nur eine kleine Anzahl verschiedener Werte, die in
@code{ENUM} umgewandelt werden, bevor die Huffman-Kompression durchgeführt
wird.

@item zero
Die Anzahl von Spalten, bei denen alle Werte 0 sind.

@item Original trees
Die anfängliche Anzahl von Huffman-Bäumen.

@item After join
Die Anzahl von unterschiedlichen Huffman-Bäumen, die übrig sind, nachdem
Bäume zusammengefasst wurden, um etwas Header-Platz zu sparen.
@end table

Nachdem eine Tabelle komprimiert wurde, gibt @code{myisamchk -dvv}
zusätzliche Informationen über jedes Feld aus:

@table @code
@item Type
Der Feldtyp kann folgende Deskriptoren enthalten:

@table @code
@item constant
Alle Zeilen haben denselben Wert.

@item no endspace
Kein Leerzeichen am Ende speichern.

@item no endspace, not_always
Kein Leerzeichen am Ende speichern und bei allen Werten keine Komprimierung
für Leerzeichen am Ende durchführen.

@item no endspace, no empty
Kein Leerzeichen am Ende speichern. Keine leeren Werte speichern.

@item table-lookup
Die Spalte wurde zu @code{ENUM} umgewandelt.

@item zerofill(n)
Die wichtigsten @code{n} Bytes im Wert sind immer 0 und wurden nicht
gespeichert.

@item no zeros
Keine Nullen speichern.

@item always zero
0-Werte sind in 1 Bit gespeichert.
@end table

@item Huff tree
Der Huffman-Baum, der zu dem Feld gehört.

@item Bits
Die Anzahl von Bits, die im Huffman-Baum benutzt werden.
@end table

Nachdem Sie @code{pack_isam}/@code{myisampack} laufen gelassen haben,
müssen Sie @code{isamchk} / @code{myisamchk} laufen lassen, um den Index
neu zu erzeugen. Zugleich können Sie die Index-Blöcke sortieren und die
Statistiken erzeugen, die benötigt werden, damit der MySQL-Optimierer
effizienter läuft:

@example
myisamchk -rq --analyze --sort-index tabelle.MYI
isamchk   -rq --analyze --sort-index tabelle.ISM
@end example

Nachdem Sie die komprimierte Tabelle ins MySQL-Datenbank-Verzeichnis
gespielt haben, müssen Sie @code{mysqladmin flush-tables} ausführen, um
@code{mysqld} anzuweisen, die neue Tabelle zu benutzen.

Wenn Sie eine gepackte Tabelle entpacken wollen, können Sie das mit der
@code{--unpack}-Option für @code{isamchk} oder @code{myisamchk} tun.


@node mysqld-max,  , myisampack, Server-Side Scripts
@c German node mysqld-max
@subsection mysqld-max, ein erweiterter mysqld-Server

@cindex @code{mysqld-max}

@code{mysqld-max} ist der MySQL-Server (@code{mysqld}), der mit folgenden
configure-Optionen konfiguriert wurde:

@multitable @columnfractions .3 .7
@item @strong{Option} @tab @strong{Kommentar}
@item --with-server-suffix=-max @tab Zur @code{mysqld}-Versionszeichenkette ein Suffix hinzufügen.
@item --with-bdb @tab Unterstützung für Berkeley-DB-(BDB)-Tabellen
@item --with-innodb @tab Unterstützung für InnoDB-Tabellen.
@item CFLAGS=-DUSE_SYMDIR @tab Symbolische-Links-Unterstützung für Windows.
@end multitable

Sie finden die MySQL-max-Binärdateien unter
@uref{http://www.mysql.com/downloads/mysql-max-3.23.html}.

Die Windows-MySQL-3.23-Binärdistribution beinhaltet sowohl die
Standard-@code{mysqld.exe}-Binärdatei als auch die
@code{mysqld-max.exe}-Binärdatei.
@uref{http://www.mysql.com/downloads/mysql-3.23.html}.
@xref{Windows installation}.

Beachten Sie, dass, weil InnoDB und Berkeley-DB nicht für alle Plattformen
verfügbar sind, einige der @code{Max}-Binärdateien eventuell noch
Unterstützung für diese beiden Typen haben. Sie können überprüfen, welche
Tabellentypen unterstützt werden, indem Sie die folgende Anfrage ausführen:

@example
mysql> show variables like "have_%";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| have_bdb      | YES   |
| have_innodb   | NO    |
| have_isam     | YES   |
| have_raid     | NO    |
| have_openssl  | NO    |
+---------------+-------+
@end example

Die Bedeutung dieser Werte ist:

@multitable @columnfractions .3 .7
@item @strong{Wert} @tab @strong{Bedeutung}.
@item YES @tab Die Option ist aktiviert und benutzbar.
@item NO @tab MySQL ist nicht mit Unterstützung für diese Option kompiliert.
@item DISABLED @tab Die xxxx-Option ist deaktiviert, weil @code{mysqld} mit @code{--skip-xxxx} gestartet wurde oder weil @code{mysqld} nicht mit allen notwendigen Optionen gestartet wurde, um die Option zu aktivieren. In diesem Fall sollte die @code{hostname.err}-Datei den Grund dafür enthalten, warum die Option deaktiviert wurde.
@end multitable

@strong{HINWEIS}: Um InnoDB-Tabellen erzeugen zu können, @strong{MÜSSEN}
Sie Ihre Startoptionen editieren und zumindest die
@code{innodb_data_file_path}-Option eingeben. @xref{InnoDB start}.

Um bessere Performance für BDB-Tabellen zu erzielen, sollten Sie auch für
diese einige Konfigurationsoptionen angeben. @xref{BDB start}.

@code{safe_mysqld} versucht automatisch, eine @code{mysqld}-Binärdatei mit
dem @code{-max}-Präfix zu starten. Das macht es sehr einfach, eine andere
@code{mysqld}-Binärdatei in einer bestehenden Installation auszutesten.
Lassen Sie einfach @code{configure} mit den Optionen, die Sie wollen,
laufen, und installieren Sie dann die neue @code{mysqld}-Binärdatei als
@code{mysqld-max} im selben Verzeichnis, wo Ihre alte
@code{mysqld}-Binärdatei liegt. @xref{safe_mysqld, , @code{safe_mysqld}}.

Der @code{mysqld-max}-RPM benutzt das oben erwähnte
@code{safe_mysqld}-Feature. Er installiert nur die ausführbare Datei
@code{mysqld-max} und @code{safe_mysqld} benutzt diese automatisch, wenn
@code{safe_mysqld} neu gestartet wird.

Folgende Tabelle zeigt, welche Tabellentypen unsere
Standard-@strong{MySQL-Max}-Binärdateien beinhalten:

@multitable @columnfractions .4 .3 .3
@item @strong{System} @tab @strong{BDB} @tab @strong{InnoDB}
@item AIX 4.3            @tab NEIN @tab JA
@item HP-UX 11.0         @tab NEIN @tab JA
@item Linux-Alpha        @tab NEIN @tab JA
@item Linux-Intel        @tab JA   @tab JA
@item Linux-Ia64         @tab NEIN @tab JA
@item Solaris-intel      @tab NEIN @tab JA
@item Solaris-sparc      @tab JA   @tab JA
@item Caldera (SCO) OSR5 @tab JA   @tab JA
@item UnixWare           @tab JA   @tab JA
@item Windows/NT         @tab JA   @tab JA
@end multitable


@node Client-Side Scripts, Log Files, Server-Side Scripts, MySQL Database Administration
@c German node Clientseitige Skripte
@section Clientseitige Skripte und Hilfsprogramme von MySQL



@menu
* Client-Side Overview::        
* mysql::                       
* mysqladmin::                  
* Using mysqlcheck::            
* mysqldump::                   
* mysqlhotcopy::                
* mysqlimport::                 
* mysqlshow::                   
* perror::                      
* Batch Commands::              
@end menu

@node Client-Side Overview, mysql, Client-Side Scripts, Client-Side Scripts
@c German node Überblick über die clientseitigen Skripte
@subsection Überblick über die clientseitigen Skripte und Dienstprogramme

@cindex Umgebungsvariablen
@cindex Programme, Auflistung

Alle MySQL-Clients, die mittels der @code{mysqlclient}-Bibliothek mit dem
Server kommunizieren, benutzen folgende Umgebungsvariablen:

@tindex @code{MYSQL_UNIX_PORT}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_UNIX_PORT}
@tindex @code{MYSQL_TCP_PORT}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_TCP_PORT}
@tindex @code{MYSQL_PWD}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_PWD}
@tindex @code{MYSQL_DEBUG}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_DEBUG}
@multitable @columnfractions .25 .75
@item @strong{Name} @tab @strong{Beschreibung}
@item @code{MYSQL_UNIX_PORT} @tab Der vorgabemäßige Socket, benutzt für Verbindungen zu @code{localhost}
@item @code{MYSQL_TCP_PORT}  @tab Der vorgabemäßige TCP/IP-Port
@item @code{MYSQL_PWD} @tab Das vorgabemäßige Passwort
@item @code{MYSQL_DEBUG} @tab Debug-Trace-Optionen beim Debuggen
@item @code{TMPDIR} @tab Das Verzeichnis, in dem temporäre Tabellen / Dateien erzeugt werden
@end multitable

Die Benutzung von @code{MYSQL_PWD} ist unsicher.
@xref{Connecting}.

@tindex @code{MYSQL_HISTFILE}-Umgebungsvariable
@tindex Umgebungsvariable, @code{MYSQL_HISTFILE}
@tindex @code{HOME}-Umgebungsvariable
@tindex Umgebungsvariable, @code{HOME}
@cindex History-Datei
@cindex Kommandozeilen-History
@tindex .mysql_History-Datei
Der @file{mysql}-Client benutzt die Datei in der @code{MYSQL_HISTFILE}-
Umgebungsvariablen genannte Datei, um die Kommandozeilen-History zu
speichern. Der Vorgabewert für die History-Datei ist
@file{$HOME/.mysql_history}, wobei @code{$HOME} der Wert der
@code{HOME}-Umgebungsvariablen ist. @xref{Environment variables}.

Alle MySQL-Programme haben viele verschiedene Optionen. Jedes 
MySQL-Programm stellt jedoch ein @code{--help}-Option zur Verfügung, die
Sie benutzen können, um eine vollständige Beschreibung der verschiedenen
Optionen des Programms zu erhalten. Probieren Sie zum Beispiel @code{mysql
--help} aus.

Sie können die vorgabemäßigen Optionen für alle Standard-Client-Programme
mit einer Optionsdatei überschreiben. @ref{Option files}.

Die unten stehende Liste beschreibt kurz die MySQL-Programme:

@table @code
@cindex @code{myisamchk}
@item myisamchk
Dienstprogramm zur Beschreibung, Prüfung, Optimierung und Reparatur von
MySQL-Tabellen. Weil @code{myisamchk} viele Funktionen hat, ist es in einem
eigenen Kapitel beschrieben. @xref{MySQL Database Administration}.

@cindex @code{make_binary_distribution}
@item make_binary_distribution
Macht ein Binär-Release eines kompilierten MySQL. Dieses könnte über FTP an
@file{/pub/mysql/Incoming} oder an @code{Support.mysql.com} geschickt
werden, damit andere MySQL-Benutzer es benutzen können.

@cindex @code{msql2mysql}
@item msql2mysql
Ein Shell-Skript, das @code{mSQL}-Programme zu MySQL konvertiert. Es deckt
nicht alle Fälle ab, ist aber hilfreich, um mit dem Konvertieren
anzufangen.

@cindex @code{mysqlaccess}
@item mysqlaccess
Ein Skript, das die Zugriffsberechtigungen für eine Host-, Benutzer- und
Datenbank-Kombination prüft.

@cindex @code{mysqladmin}
@item mysqladmin
Dienstprogramm für die Durchführung von Verwaltungsoperationen wie Erzeugen
und Löschen von Datenbanken, Neulanden der Berechtigungstabellen,
Zurückschreiben von Tabellen auf Platte und Neuöffnen von Log-Dateien.
@code{mysqladmin} kann auch benutzt werden, um Versionsnummer sowie Status-
und Prozess-Informationen vom Server zu erhalten.
@xref{mysqladmin, , @code{mysqladmin}}.

@cindex @code{mysqlbug}
@item mysqlbug
Das MySQL-Bug-Bericht-Skript. Dieses Skript sollte immer benutzt werden,
wenn Sie einen Bug-Bericht an die MySQL-Liste ausfüllen.

@cindex @code{mysqld}
@item mysqld
Der SQL-Daemon. Dieser sollte immer laufen.

@cindex @code{mysqldump}
@item mysqldump
Dumpt eine MySQL-Datenbank in eine Datei als SQL-Statements oder als
Tabulator-separierte Textdateien. Verbesserte Freeware, ursprünglich von
Igor Romanenko. @xref{mysqldump, , @code{mysqldump}}.

@cindex @code{mysqlimport}
@item mysqlimport
Importiert Textdateien in die jeweiligen Tabellen mittels @code{LOAD DATA
INFILE}. @xref{mysqlimport, , @code{mysqlimport}}.

@cindex @code{mysqlshow}
@item mysqlshow
Zeigt Informationen über Datenbanken, Tabellen, Spalten und Indexe an.

@cindex @code{mysql_install_db}
@item mysql_install_db
Erzeugt die MySQL-Berechtigungstabellen mit vorgabemäßigen Berechtigungen.
Dieses Skript wird gewöhnlich nur einmal ausgeführt, wenn Sie MySQL das
erste Mal auf einem System installieren.

@cindex @code{replace}
@item replace
Ein Dienstprogramm, das von @code{msql2mysql} benutzt wird, aber auch
darüber hinaus benutzt werden kann. @code{replace} ändert Zeichenketten in
Dateien oder auf der Standardeingabe. Benutzt eine finite Status-Maschine,
um zuerst Übereinstimmung mit längeren Zeichenketten zu finden. Kann
benutzt werden, um Zeichenketten umzudrehen. Der folgende Befehl zum
Beispiel dreht @code{a} und @code{b} in den angegebenen Dateien um:

@example
shell> replace a b b a --Datei1 Datei2 ...
@end example
@end table


@node mysql, mysqladmin, Client-Side Overview, Client-Side Scripts
@c German node mysql
@subsection Das Kommandozeilen-Werkzeug

@cindex Kommandozeilen-Werkzeug
@cindex Werkzeuge, Kommandozeile
@cindex Skripte
@cindex @code{mysql}

@code{mysql} ist eine einfache SQL-Shell (mit GNU
@code{readline}-Fähigkeiten). Sie unterstützt interaktiven und nicht
interaktiven Gebrauch. Wenn sie interaktiv benutzt wird, werden
Anfrageergebnisse in einem ASCII-Tabellenformat ausgegeben. Wenn sie nicht
interaktiv benutzt wird (zum Beispiel als Filter), wird das Ergebnis in
Tabulator-separiertem Format ausgegeben. (Das Ausgabeformat kann mit den
Kommandozeilenoptionen geändert werden.) Skripte können Sie einfach wie
folgt laufen lassen:

@example
shell> mysql datenbank < skript.sql > ausgabe.tab
@end example

Wenn Sie Probleme haben, die auf ungenügenden Speicher beim Client
zurückzuführen sind, benutzen Sie die @code{--quick}-Option! Diese zwingt
@code{mysql}, @code{mysql_use_result()} statt @code{mysql_store_result()}
zu benutzen, um die Ergebnismenge zu holen.

Die Benutzung von @code{mysql} ist sehr einfach. Starten Sie es einfach wie
folgt:
@code{mysql datenbank} oder @code{mysql --user=benutzername
--password=ihr_passwort datenbank}. Geben Sie ein SQL-Statement ein,
beenden Sie es mit @samp{;}, @samp{\g} oder @samp{\G}, und drücken Sie die
Eingabetaste.

@cindex @code{mysql}-Kommandozeilenoptionen
@cindex Kommandozeilenoptionen, @code{mysql}
@cindex Optionen, Kommandozeile, @code{mysql}
@cindex Startparameter, @code{mysql}
@code{mysql} unterstützt folgende Optionen:

@table @code
@cindex @code{help}, @code{mysql}-Option
@item -?, --help
Hilfetext ausgeben und beenden.

@cindex @code{no-auto-rehash}, @code{mysql}-Option
@item -A, --no-auto-rehash
Kein automatisches Rehashing. Man muss 'rehash' benutzen, um Tabellen- und
Feld-Vervollständigung zu erhalten. Durch die Option wird mysql schneller
gestartet.

@cindex @code{batch}, @code{mysql}-Option
@item -B, --batch
Ergebnisse mit einem Tabulator als Trennzeichen ausgeben, jede
Tabellenzeile auf einer neuen Zeile. Keine History-Datei benutzen.

@cindex @code{character-sets-dir}, @code{mysql}-Option
@item --character-sets-dir=...
Verzeichnis, in dem sich die Zeichensätze befinden.

@cindex @code{compress}, @code{mysql}-Option
@item -C, --compress
Im Client-Server-Protokoll Komprimierung benutzen.

@cindex @code{debug}, @code{mysql}-Option
@item -#, --debug[=...]
Debug loggen. Vorgabe ist 'd:t:o,/tmp/mysql.trace'.

@cindex @code{database}, @code{mysql}-Option
@item -D, --database=...
Datenbank, die benutzt werden soll. Hauptsächlich nützlich in der
@code{my.cnf}-Datei.

@cindex @code{default-character-set}, @code{mysql}-Option
@item --default-character-set=...
Den vorgabemäßigen Zeichensatz setzen.

@cindex @code{execute}, @code{mysql}-Option
@item -e, --execute=...
Befehl ausführen und beenden. (Ausgabe wie bei --batch)

@cindex @code{vertical}, @code{mysql}-Option
@item -E, --vertical
Ausgabe einer Anfrage (Zeilen) vertikal darstellen. Ohne diese Option
können Sie diese Ausgabe auch dadurch erzwingen, dass Sie Ihre Statements
mit @code{\G} beenden.

@cindex @code{force}, @code{mysql}-Option
@item -f, --force
Weitermachen, auch wenn ein SQL-Fehler auftritt.

@cindex @code{no-named-commands}, @code{mysql}-Option
@item -g, --no-named-commands
Benannte Befehle werden deaktiviert. Benutzen Sie nur die \*-Form, oder
benutzen Sie benannte Befehle nur bei Zeilen, die mit einem Semikolon
enden. Ab Version 10.9 startet der Client vorgabemäßig mit ANGESCHALTETER
Option! Wenn die -g-Option angeschaltet ist, funktionieren Befehle im
Langformat jedoch immer noch von der ersten Zeile aus.

@cindex @code{enable-named-commands}, @code{mysql}-Option
@item -G, --enable-named-commands
Benannte Befehle sind @strong{angeschaltet}. Befehle im Langformat sind
ebenso zugelassen wie die abgekürzten \*-Befehle.

@cindex @code{ignore-space}, @code{mysql}-Option
@item -i, --ignore-space
Leerzeichen nach Funktionsnamen ignorieren.

@cindex @code{host}, @code{mysql}-Option
@item -h, --host=...
Connect to the given host.

@cindex @code{html}, @code{mysql}-Option
@item -H, --html
HTML-Ausgabe produzieren.

@cindex @code{skip-line-numbers}, @code{mysql}-Option
@item -L, --skip-line-numbers
Bei Fehlern keine Zeilennummer ausgeben. Nützlich, wenn man mit
Ergebnisdateien vergleichen will, die Fehlermeldungen enthalten.

@cindex @code{no-pager}, @code{mysql}-Option
@item --no-pager
Pager deaktivieren und nach stdout ausgeben. Siehe auch interaktive Hilfe
(\h).

@cindex @code{no-tee}, @code{mysql}-Option
@item --no-tee
Ausgabedatei (Outfile) deaktivieren. Siehe auch interaktive Hilfe (\h).

@cindex @code{unbuffered}, @code{mysql}-Option
@item -n, --unbuffered
Nach jeder Anfrage Buffer zurückschreiben (flush).

@cindex @code{skip-column-names}, @code{mysql}-Option
@item -N, --skip-column-names
In Ergebnissen keine Spaltennamen ausgeben.

@cindex @code{set-variable}, @code{mysql}-Option
@item -O, --set-variable var=option
Einer Variablen einen Wert zuweisen. @code{--help} listet Variablen auf.

@cindex @code{one-database}, @code{mysql}-Option
@item -o, --one-database
Nur die vorgabemäßige Datenbank aktualisieren. Das ist nützlich, wenn man
in der Update-Logdatei Aktualisierungen (Updates) auf eine andere Datenbank
überspringen will.

@cindex @code{pager}, @code{mysql}-Option
@item @code{--pager[=...]}
Ausgabetyp. Vorgabe ist Ihre @code{ENV}-Variable @code{PAGER}. Gültige
Pager sind less, more, cat [> Dateiname] usw. Siehe auch interaktive Hilfe
(\h). Diese Option funktioniert nicht im Stapelmodus. Der Pager
funktioniert nur unter UNIX.

@cindex @code{password}, @code{mysql}-Option
@item -p[password], --password[=...]
Passwort, das für die Verbindung zum Server benutzt wird. Wenn das Passwort
nicht auf der Kommandozeile angegeben wird, wird eine Eingabeaufforderung
dafür ausgegeben. Beachten Sie: Wenn Sie die Kurzform @code{-p} benutzen,
darf zwischen der Option und dem Passwort kein Leerzeichen stehen.

@cindex @code{port}, @code{mysql}-Option
@item -P  --port=...
TCP/IP-Portnummer, die für die Verbindung benutzt wird.

@cindex @code{quick}, @code{mysql}-Option
@item -q, --quick
Ergebnisse nicht cachen, Zeile für Zeile ausgeben. Das kann den Server
verlangsamen, wenn die Ausgabe verschoben wird. Keine History-Datei
benutzen.

@cindex @code{raw}, @code{mysql}-Option
@item -r, --raw
Spaltenwerte ohne Escape-Umwandlung schreiben. Benutzt für @code{--batch}.

@cindex @code{silent}, @code{mysql}-Option
@item -s, --silent
Schweigsamer sein.

@cindex @code{socket}, @code{mysql}-Option
@item -S  --socket=...
Socket-Datei, die für die Verbindung benutzt wird.

@cindex @code{table}, @code{mysql}-Option
@item -t  --table
Ausgabe im Tabellenformat. Das ist die Vorgabe im Nicht-Stapelmodus.

@cindex @code{debug-info}, @code{mysql}-Option
@item -T, --debug-info
Beim Verlassen einige Debug-Informationen ausgeben.

@cindex @code{tee}, @code{mysql}-Option
@item --tee=...
Alles an die Ausgabedatei anhängen. Siehe auch interaktive Hilfe (\h).
Funktioniert nicht im Stapelmodus.

@cindex @code{user}, @code{mysql}-Option
@item -u, --user=#
Benutzer zum Einloggen, falls nicht der aktuelle UNIX-Benutzer.

@cindex @code{safe-updates}, @code{mysql}-Option
@item -U, --safe-updates[=#], --i-am-a-dummy[=#]
Läßt nur @code{UPDATE} und @code{DELETE} zu, die Schlüssel benutzen. Siehe
unten wegen weiterer Informationen über diese Option. Sie können diese
Option zurücksetzen, wenn Sie sie in Ihrer @code{my.cnf}-Datei haben, indem
Sie @code{--safe-updates=0} benutzen.

@cindex @code{verbose}, @code{mysql}-Option
@item -v, --verbose
Geschwätzigere Ausgabe (-v -v -v ergibt das Tabellen-Ausgabeformat).

@cindex @code{version}, @code{mysql}-Option
@item -V, --version
Versionsinformationen ausgeben und beenden.

@cindex @code{wait}, @code{mysql}-Option
@item -w, --wait
Wenn die Verbindung geschlossen wurde, warten und noch einmal versuchen,
statt abzubrechen.
@end table

Mit @code{-O} oder @code{--set-variable} können Sie auch die folgenden
Variablen setzen:

@cindex timeout, @code{connect_timeout}-Variable
@cindex @code{connect_timeout}-Variable
@cindex @code{max_allowed_packet}
@cindex @code{net_buffer_length}
@cindex @code{select_limit}
@cindex @code{max_join_size}
@multitable @columnfractions .3 .2 .5
@item Variablenname      @tab Vorgabe   @tab Beschreibung
@item connect_timeout    @tab 0         @tab Anzahl von Sekunden, bevor die Verbindung wegen Zeitüberschreitung abgebrochen wird
@item max_allowed_packet @tab 16777216  @tab Maximale Paketlänge, die zum Server gesendet bzw. von diesem empfangen wird
@item net_buffer_length  @tab 16384     @tab Puffer für TCP/IP- und Socket-Kommunikation
@item select_limit       @tab 1000      @tab Automatisches Limit für SELECT bei Benutzung von --i-am-a-dummy
@item max_join_size      @tab 1000000   @tab Automatisches Limit für Zeilen in einem Join bei Benutzung von --i-am-a-dummy.
@end multitable

Wenn Sie 'help' auf der Kommandozeile eingeben, gibt @code{mysql} die
Befehle aus, die es unterstützt:

@cindex Befehle, Auflistung
@example
mysql> help

MySQL-Befehle:
help    (\h)    Diesen Text anzeigen.
?       (\h)    Synonym für `help'.
clear   (\c)    Lösch-Befehl.
connect (\r)    Erneut mit dem Server verbinden. Optionale Argumente sind db und host.
edit    (\e)    Befehl mit $EDITOR editieren.
ego     (\G)    Befehl an den MySQL-Server schicken, Ergebnis vertikal anzeigen.
exit    (\q)    mysql beenden. Dasselbe wie quit.
go      (\g)    Befehl an den MySQL-Server schicken.
nopager (\n)    Pager deaktivieren, nach stdout ausgeben.
notee   (\t)    Nicht in die Ausgabedatei (Outfile) schreiben.
pager   (\P)    PAGER [auf_pager] setzen. Anfrageergebnisse über PAGER ausgeben.
print   (\p)    Aktuellen Befehl ausgeben.
quit    (\q)    mysql beenden.
rehash  (\#)    Vervollständigungs-Hash neu aufbauen.
source  (\.)    Eine SQLsSkriptdatei ausführen. Benötigt einen Dateinamen als Argument.
status  (\s)    Statusinformationen vom Server abrufen.
tee     (\T)    Ausgabedatei [auf_outfile] setzen. Alles an die angegebene Ausgabedatei anhängen.
use     (\u)    Eine andere Datenbankbenutzung. Benötigt Datenbanknamen als Argument.
@end example

Bei diesen Befehlen funktioniert PAGER nur unter UNIX.

@cindex status command
Der @code{status}-Befehl gibt Ihnen einige Informationen über die
Verbindung und den Server, den Sie benutzen. Wenn der Server im
@code{--safe-updates}-Modus läuft, gibt @code{status} auch die Werte der
@code{mysql}-Variablen aus, die Ihre Anfragen beeinflussen.

@cindex @code{safe-mode}-Befehl
Eine nützliche Startoption für Anfänger (eingeführt in MySQL-Version
3.23.11) ist @code{--safe-updates} (oder @code{--i-am-a-dummy} für
Benutzer, die irgendwann ein @code{DELETE FROM tabelle} eingeben, aber
vergessen, die @code{WHERE}-Klausel) zu benutzen. Wenn Sie diese Option
benutzen, schickt @code{mysql} beim Öffnen der Verbindung folgenden Befehl
an den MySQL-Server:

@example
SET SQL_SAFE_UPDATES=1,SQL_SELECT_LIMIT=#select_limit#,
    SQL_MAX_JOIN_SIZE=#max_join_size#"
@end example

Wobei @code{#select_limit#} und @code{#max_join_size#} Variablen sind, die
auf der @code{mysql}-Kommandozeile gesetzt werden können.
@c German FIX unsplit @xref
@xref{SET OPTION}.

Die Auswirkung davon ist folgende:

@itemize @bullet
@item
@code{UPDATE}- oder @code{DELETE}-Statements ohne Schlüsselbeschränkung im
@code{WHERE}-Teil sind nicht zugelassen. Man kann jedoch ein
@code{UPDATE/DELETE} durch die Benutzung von @code{LIMIT} erzwingen:
@example
UPDATE tabelle SET not_key_column=# WHERE not_key_column=# LIMIT 1;
@end example
@item
Alle großen Ergebnisse werden automatisch auf @code{#select_limit#} Zeilen
begrenzt.
@item
@code{SELECT}'s, die wahrscheinlich mehr als @code{#max_join_size}
Zeilenkombinationen durchgehen müssen, werden abgebrochen.
@end itemize

Einige nützliche Anmerkungen zum @code{mysql}-Client:

Einige Daten sind lesbarer, wenn sie vertikal angezeigt werden statt auf
die übliche horizontale kastenähnliche Art. Langer Text zum Beispiel, der
Zeilenumbrüche beinhaltet, ist bei vertikaler Ausgabe meist viel einfacher
zu lesen.

@example
mysql> select * from mails where length(txt) < 300 limit 300,1\G
*************************** 1. row ***************************
  msg_nro: 3068
     date: 2000-03-01 23:29:50
time_zone: +0200
mail_from: Monty
    reply: monty@@no.spam.com
  mail_to: "Thimble Smith" <tim@@no.spam.com>
      sbj: UTF-8
      txt: >>>>> "Thimble" == Thimble Smith writes:

Thimble> Hi. Meines Erachtens eine gute Idee. Kennt sich jemand mit UTF-8
Thimble> oder Unicode aus? Ansonsten packe ich das auf meine TODO-Liste
Thimble> und warte, was passiert.

Ja, mach das bitte!

Regards,
Monty
    Datei: inbox-jani-1
     hash: 190402944
1 row in set (0.09 sec)
@end example

@itemize @bullet
@item
Zum Mitloggen benutzen Sie die @code{tee}-Option. @code{tee} wird mit der
Option @code{--tee=...} oder interaktiv auf der Kommandozeile mi dem Befehl
@code{tee} gestartet. Alle Daten, die auf dem Bildschirm erscheinen, werden
auch in die angegebene Datei geschrieben. Das kann auch für Debug-Zwecke
sehr hilfreich sein. @code{tee} kann von der Kommandozeile aus mit dem
Befehl @code{notee} deaktiviert werden. Wenn @code{tee} noch einmal
eingegeben wird, wird wiederum mit dem Loggen begonnen. Ohne Parameter wird
die vorherige Datei wiederum benutzt. Beachten Sie, dass @code{tee} die
Ergebnisse nach jedem Befehl in die Datei zurückschreibt, direkt bevor die
Kommandozeilenaufforderung für den nächsten Befehl erscheint.

@item
Das Durchstöbern oder Durchsuchen der Ergebnisse im interaktiven Modus in
UNIX-less, -more oder einem ähnlichen Programm ist jetzt möglich mit der
Option @code{--pager[=...]}. Ohne Argument aufgerufen sieht der
@code{mysql}-Client in der Umgebungsvariablen PAGER nach und setzt
@code{pager} auf diesen Wert. @code{pager} kann von der interaktiven
Kommandozeile mit dem Befehl @code{pager} gestartet und mit @code{nopager}
deaktiviert werden. Optional nimmt der Befehl ein Argument entgegen und
setzt @code{pager} darauf. @code{pager} kann ohne Argument aufgerufen
werden, aber das erfordert, dass die Option @code{--pager} benutzt wurde,
ansonsten gibt @code{pager} in stdout aus. @code{pager} funktioniert nur
unter UNIX, denn es benutzt die popen()-Funktion, die es unter Windows
nicht gibt. Unter Windows kann statt dessen die @code{tee}-Option benutzt
werden, wenngleich diese in manchen Situationen nicht ganz so handlich ist
wie @code{pager}.

@item
Ein paar Tipps zu @code{pager}: Sie können es benutzen, um in eine Datei zu
schreiben:
@example
mysql> pager cat > /tmp/log.txt
@end example
Die Ergebnisse werden nur in eine Datei geschrieben. Sie können auch
Optionen an Programme übergeben, die Sie mit @code{pager} zusammen benutzen
wollen:
@example
mysql> pager less -n -i -S
@end example
Beachten Sie hierbei die Option '-S'. Beim Durchstöbern der Ergebnisse
werden Sie diese wahrscheinlich als sehr nützlich erachten. Probieren Sie
dei Option mit horizontaler Ausgabe (Befehle enden mit '\g', oder ';') und
mit vertikaler Ausgabe (Befehle enden mit '\G') aus. Manchmal ist ein sehr
breites Ergebnis schwer am Bildschirm zu lesen. Mit der Option -S für less
können Sie die Ergebnisse im interaktiven less von links nach rechts
durchstöbern, wobei verhindert wird, dass Zeilen, die länger sind als Ihre
Bildschirmbreite, in die nächste Zeile umgebrochen werden. Das kann ein
Ergebnis sehr viel lesbarer gestalten. Sie können den Modus im interaktiven
less an- und abschalten, wenn Sie '-S' benutzen. Siehe 'h' für weitere
Hilfe zu less.

@item
Zum Schluss (falls Sie das nicht schon aus den oben aufgeführten Beispielen
heraus gefunden haben ;-) können Sie sehr komplexe Dinge tun, um die
Ergebnisse zu handhaben. Folgendes würde die Ergebnisse beispielsweise an
zwei verschiedene Dateien in zwei unterschiedlichen Verzeichnissen
schicken, auf zwei unterschiedlichen Festplatten, die auf /dr1 und /dr2
gemountet sind, und dennoch die Ergebnisse über less am Bildschirm
anzeigen:
@example
mysql> pager cat | tee /dr1/tmp/res.txt | tee /dr2/tmp/res2.txt | less -n -i -S
@end example

@item
Sie können die obigen Funktionen auch kombinieren, indem Sie @code{tee}
anschalten und @code{pager} auf 'less' setzen. Dann können Sie die
Ergebnisse in 'less' durchstöbern und trotzdem wird alles zugleich an eine
Datei angehängt. Der Unterschied zwischen @code{UNIX tee}, was mit
@code{pager} benutzt wird, und dem im @code{mysql}-Client eingebauten
@code{tee} ist, dass das eingebaute @code{tee} sogar dann funktioniert,
wenn kein @code{UNIX tee} verfügbar ist. Darüber hinaus gibt das eingebaute
@code{tee} alles, was mitgeloggt wird, auch am Bildschirm aus, wohingegen
das @code{UNIX tee} in Verbindung mit @code{pager} nicht so viel mitloggt.
Letztlich läßt sich das interaktive @code{tee} auch handlicher aus- und
einschalten, wenn Sie teilweise mitloggen wollen, aber in der Lage sein,
das Feature zwischendurch auszuschalten.
@end itemize


@node mysqladmin, Using mysqlcheck, mysql, Client-Side Scripts
@c German node mysqladmin
@subsection mysqladmin, Verwaltung eines MySQL-Servers

@cindex Administration, Server
@cindex Serververwaltung
@cindex @code{mysladmn}

Ein Dienstprogramm, um Verwaltungsoperationen durchzuführen. Die Syntax ist::

@example
shell> mysqladmin [OPTIONS] befehl [befehl-option] befehl ...
@end example

Sie erhalten eine Auflistung der Optionen, die Ihre
@code{mysqladmin}-Version unterstützt, indem Sie @code{mysqladmin --help}
ausführen.

Das aktuelle @code{mysqladmin} unterstützt folgende Befehle:

@table @code
@item create datenbank
Eine neue Datenbank erzeugen.

@item drop datenbank
Eine Datenbank und alle ihre Tabellen löschen.

@item extended-status
Eine erweiterte Statusmeldung vom Server ausgeben.

@item flush-hosts
Alle gecacheten Hosts zurückschreiben (flush).

@item flush-logs
Alle Logs zurückschreiben (flush).

@item flush-tables
Alle Tabellen zurückschreiben (flush).

@item flush-privileges
Berechtigungstabellen neu laden (dasselbe wie reload).

@item kill id,id,...
MySQL-Threads killen.

@item password
Ein neues Passwort setzen. Altes Passwort zu neuem Passwort ändern.

@item ping
Überprüfen, ob mysqld lebt.

@item processlist
Auflistung aktiver Threads im Server.

@item reload
Berechtigungstabellen neu laden.

@item refresh
Alle Tabellen zurückschreiben (flush), Log-Dateien schließen und erneut
öffnen.

@item shutdown
Server herunter fahren.

@item slave-start
Slave-Replikations-Thread starten.

@item slave-stop
Slave-Replikations-Thread anhalten.

@item status
Eine kurze Statusmeldung vom Server ausgeben.

@item variables
Verfügbare Variablen ausgeben.

@item version
Versionsinformation vom Server abrufen.
@end table

Alle Befehle können auf ihr eindeutiges Präfix abgekürzt werden. Beispiel:

@example
shell> mysqladmin proc stat
+----+-------+-----------+----+-------------+------+-------+------+
| Id | User  | Host      | db | Command     | Time | State | Info |
+----+-------+-----------+----+-------------+------+-------+------+
| 6  | monty | localhost |    | Processlist | 0    |       |      |
+----+-------+-----------+----+-------------+------+-------+------+
Uptime: 10077  Threads: 1  Questions: 9  Slow queries: 0  Opens: 6  Flush tables: 1  Open tables: 2  Memory in use: 1092K  Max memory used: 1116K
@end example

@cindex Status-Befehl, Ergebnisse
Das Ergebnis des @code{mysqladmin status}-Befehls hat folgende Spalten:

@cindex uptime
@multitable @columnfractions .3 .7
@item Uptime @tab Anzahl von Sekunden, seit der MySQL-Server hoch gefahren ist.
@cindex Threads
@item Threads @tab Anzahl aktiver Threads (Clients).
@cindex questions
@item Questions @tab Anzahl von Questions von Clients, seit @code{mysqld} gestartet wurde.
@cindex slow queries
@item Slow queries @tab Anfragen, die länger als @code{long_query_time} Sekunden benötigten. @xref{Slow query log}.
@cindex opens
@item Opens @tab Wie viele Tabellen @code{mysqld} geöffnet hat.
@cindex flush tables
@cindex tables, flush
@item Flush Tables @tab Anzahl von @code{flush ...}-, @code{refresh}- und @code{reload}-Befehlen.
@cindex open tables
@item Open Tables @tab Anzahl der Tabellen, die gerade geöffnet sind.
@cindex memory use
@item Memory in use @tab Arbeitsspeicher, der direkt vom @code{mysqld}-Code beansprucht wird (nur verfügbar, wenn MySQL mit --with-debug=full kompiliert wurde).
@cindex max memory used
@item Max memory used @tab Maximaler Arbeitsspeicher, der direkt vom @code{mysqld}-Code beansprucht wird (nur verfügbar, wenn MySQL mit --with-debug=full kompiliert wurde).
@end multitable

Wenn Sie @code{mysqladmin shutdown} auf einem Socket ausführen (mit anderen
Worten, auf dem Computer, wo @code{mysqld} läuft), wartet
@code{mysqladmin}, bis MySQL die @code{pid-file} entfernt hat, um
sicherzustellen, dass der @code{mysqld}-Server korrekt angehalten wurde.


@node Using mysqlcheck, mysqldump, mysqladmin, Client-Side Scripts
@c German node mysqlcheck
@subsection Benutzung von @code{mysqlcheck} für Tabellenwartung und Wiederherstellung nach Abstürzen

Ab MySQL-Version 3.23.38 können Sie ein neues Prüf- und Reparatur-Werkzeug
für @code{MyISAM}-Tabellen einsetzen. Der Unterschied zu @code{myisamchk}
ist, dass @code{mysqlcheck} benutzt werden kann, wenn der
@code{mysqld}-Server läuft, wohingegen @code{myisamchk} nur benutzt werden
sollte, wenn er nicht läuft. Der Vorteil ist, dass Sie den Server zum
Prüfen oder zur Reparatur Ihrer Tabellen nicht mehr herunter fahren müssen.

@code{mysqlcheck} benutzt die MySQL-Server-Befehle @code{CHECK},
@code{REPAIR}, @code{ANALYZE} und @code{OPTIMIZE} auf eine für den Benutzer
bequeme Weise.

Es gibt drei alternative Möglichkeiten, @code{mysqlcheck} aufzurufen:

@example
shell> mysqlcheck [OPTIONS] datenbank [tabellen]
shell> mysqlcheck [OPTIONS] --databases datenbank1 [datenbank2 datenbank3...]
shell> mysqlcheck [OPTIONS] --all-databases
@end example

Daher kann es hinsichtlich der Auswahl von Datenbanken und Tabellen ähnlich
wie @code{mysqldump} benutzt werden.

@code{mysqlcheck} besitzt im Vergleich zu den anderen Clients ein
besonderes Feature: Das vorgabemäßige Verhalten, Tabellen mit -c zu
prüfen, kann geändert werden, indem die Binärdatei umbenannt wird. Wenn Sie
nur ein Werkzeug haben wollen, das vorgabemäßig Tabellen repariert,
kopieren Sie eine @code{mysqlcheck} mit einem neuen Namen auf Ihre
Festplatte, nämlich @code{mysqlrepair}, oder legen alternativ einen
symbolischen Link auf @code{mysqlrepair} und benennen den Link
@code{mysqlrepair}. Wenn Sie jetzt @code{mysqlrepair} aufrufen, repariert
es vorgabemäßig Tabellen.

Folgende Namen können Sie benutzen, um das vorgabemäßige Verhalten von
@code{mysqlcheck} zu verändern:

@example
mysqlrepair:   Vorgabe-Option: -r (reparieren)
mysqlanalyze:  Vorgabe-Option: -a (analysieren)
mysqloptimize: Vorgabe-Option: -o (optimieren)
@end example

Die verfügbaren Optionen für @code{mysqlcheck} sind hier aufgelistet. Bitte
prüfen Sie mit @code{mysqlcheck --help}, welche davon Ihre Version
unterstützt.

@table @code
@item -A, --all-databases
Prüft alle Datenbanken. Das ist dasselbe wie --databases mit allen
Datenbanken ausgewählt.
@item -1, --all-in-1
Statt für jede Tabelle eine Anfrage auszuführen, alle Anfragen in 1 Anfrage
pro Datenbank ausführen. Tabellennamen stehen in einer durch Kommas
getrennten Liste.
@item  -a, --analyze
Analysiert die angegebene Tabelle.
@item --auto-repair
Wenn eine geprüfte Tabelle beschädigt ist, sie automatisch reparieren. Die
Reparatur wird durchgeführt, nachdem alle Tabellen geprüft wurden, falls
beschädigte gefunden wurden.
@item -#, --debug=...
Debug-Log-Datei ausgeben. Das ist häufig 'd:t:o,filename'.
@item --character-sets-dir=...
Verzeichnis, wo Zeichensätze gespeichert sind.
@item -c, --check
Tabelle auf Fehler prüfen.
@item -C, --check-only-changed
Nur die Tabellen prüfen, die seit der letzten Prüfung geändert wurden oder
die nicht ordnungsgemäß geschlossen wurden.
@item --compress
Kompression im Client-Server-Protokoll benutzen.
@item -?, --help
Diese Nachricht ausgeben und beenden.
@item -B, --databases
Mehrere Datenbanken prüfen. Beachten Sie den Unterschied im Gebrauch: In
diesem Fall werden keine Tabellen angegeben. Alle Namensargumente werden
als Datenbanknamen erachtet.
@item --default-character-set=...
Setzt den vorgabemäßigen Zeichensatz.
@item -F, --fast
Nur Tabellen prüfen, die nicht ordnungsgemäß geschlossen wurden.
@item -f, --force
Fortfahren, auch wenn ein SQL-Fehler auftritt.
@item -e, --extended
Wenn Sie diese Option beim Prüfen von Tabellen benutzen, stellt das sicher,
dass die Tabelle zu 100% konsistent ist, dauert aber sehr lange.
Wenn Sie diese Option beim Reparieren von Tabellen benutzen, wird eine
erweiterte Reparatur der Tabelle durchgeführt, was nicht nur sehr lange
dauern kann, sondern auch viele 'Müll'-Zeilen produzieren kann!
@item -h, --host=...
Mit dem angegebenen Host verbinden.
@item -m, --medium-check
Schneller als extended-check, findet aber nur 99,99% aller Fehler. Sollte
in den meisten Fällen genügen.
@item -o, --optimize
Tabelle optimieren.
@item -p, --password[=...]
Passwort, das bei der Verbindung zum Server benutzt werden soll. Wenn das
Passwort nicht angegeben wird, wird vom Terminal eine Eingabeaufforderung
präsentiert.
@item -P, --port=...
Portnummer, die für Verbindungen zum Server benutzt werden soll.
@item -q, --quick
Wenn Sie diese Option beim Prüfen von Tabellen benutzen, verhindert das,
dass die Zeilen nach falschen Verknüpfungen (Links) durchgesehen werden
(gescannt). Das ist die schnellste Prüfmethode.
Wenn Sie diese Option beim Reparieren von Tabellen benutzen, wird versucht,
nur den Index-Baum zu reparieren. Das ist die schnellste Reparaturmethode.
@item -r, --repair
Kann fast alles reparieren, ausser eindeutige Schlüssel, die nicht
eindeutig sind.
@item -s, --silent
Nur Fehlermeldungen ausgeben.
@item -S, --socket=...
Socket-Datei, die für die Verbindung benutzt werden soll.
@item --tables
Option --databases (-B) überschreiben.
@item -u, --user=#
Benutzer zum Einloggen, falls nicht der aktuelle Unix-Benutzer.
@item -v, --verbose
Informationen über die verschiedenen Phasen ausgeben.
@item -V, --version
Versionsinformationen ausgeben und beenden.
@end table


@node mysqldump, mysqlhotcopy, Using mysqlcheck, Client-Side Scripts
@c German node mysqldump
@subsection mysqldump, Tabellenstrukturen und -daten dumpen

@cindex dumpen, Datenbanken
@cindex Datenbanken, dumpen
@cindex Tabellen, dumpen
@cindex Datensicherung, Datenbanken

@cindex @code{mysqldump}
Dienstprogramm, um eine Datenbank oder eine Sammlung von Datenbanken zu
sichern oder um Daten auf einen anderen SQL-Server zu übertragen (nicht
notwendigerweise ein MySQL-Server). Der Dump enthält SQL-Statements, um
Datenbanken und Tabellen zu erzeugen und / oder Tabellen mit Daten zu
füllen.

Wenn Sie eine Datensicherung auf dem Server machen, sollten Sie in Betracht
ziehen, statt dessen @code{mysqlhotcopy} zu benutzen. @xref{mysqlhotcopy, ,
@code{mysqlhotcopy}}.

@example
shell> mysqldump [OPTIONS] datenbank [tabellen]
OR     mysqldump [OPTIONS] --databases [OPTIONS] datenbank1 [datenbank2 datenbank3...]
OR     mysqldump [OPTIONS] --all-databases [OPTIONS]
@end example

Wenn Sie keine Tabellen angeben oder @code{--databases} bzw.
@code{--all-databases} benutzen, wird die gesamte Datenbank (bzw. werden
alle Datenbanken) gedumpt.

Sie erhalten eine Auflistung der Optionen, die Ihre Version von
@code{mysqldump} unterstützt, indem Sie @code{mysqldump --help} eingeben.

Wenn Sie @code{mysqldump} ohne @code{--quick} oder @code{--opt} ausführen,
beachten Sie, dass @code{mysqldump} die gesamte Ergebnismenge in den
Arbeitsspeicher lädt, bevor das Ergebnis gedumpt wird. Das kann zu
Problemen führen, wenn Sie eine große Datenbank dumpen.

Wenn Sie eine neue Version des @code{mysqldump}-Programms benutzen und
einen Dump erzeugen, der in einen sehr alten MySQL-Server eingelesen werden
soll, sollten Sie die @code{--opt}- und @code{-e}-Optionen nicht benutzen.

@code{mysqldump} unterstützt folgende Optionen:

@table @code
@item --add-locks
Führt @code{LOCK TABLES} vor und @code{UNLOCK TABLE} nach jedem
Tabellen-Dump durch (um schnelleres Einfügen in MySQL zu erreichen).
@item --add-drop-table
Ein @code{drop table} vor jedem @code{create}-Statement hinzufügen.
@item -A, --all-databases
Alle Datenbanken dumpen. Das ist dasselbe wie @code{--databases} mit allen
Datenbanken ausgewählt.
@item -a, --all
Alle MySQL-spezifischen Optionen für @code{create} benutzen.
@item --allow-keywords
Erzeugung von Spaltennamen zulassen, die Schlüsselwörter sind. Das
funktioniert, indem jedem Spaltenname der Tabellenname als Präfix angefügt
wird.
@item -c, --complete-insert
Vollständige @code{insert}-Statements benutzen (mit Spaltennamen).
@item -C, --compress
Alle Informationen zwischen Client und Server komprimieren, wenn bei
Kompression unterstützen.
@item -B, --databases
Mehrere Datenbanken prüfen. Beachten Sie den Unterschied im Gebrauch: In
diesem Fall werden keine Tabellen angegeben. Alle Namensargumente werden
als Datenbanknamen erachtet. Vor jeder Ausgabe einer neuen Datenbank wird
@code{USE datenbank;} eingefügt.
@item --delayed
Zeilen mit dem @code{INSERT DELAYED}-Befehl einfügen.
@item -e, --extended-insert
Die neue mehrzeilige @code{INSERT}-Syntax benutzen. (Ergibt kompaktere und
schnellere inserts-Statements.)
@item -#, --debug[=option_string]
Programmbenutzung tracen (für Debug-Zwecke).
@item --help
Hilfetext ausgeben und beenden.
@item --fields-terminated-by=...
@itemx --fields-enclosed-by=...
@itemx --fields-optionally-enclosed-by=...
@itemx --fields-escaped-by=...
@itemx --lines-terminated-by=...
Diese Optionen werden zusammen mit der @code{-T}-Option benutzt und haben
dieselbe Bedeutung wie die entsprechenden Klauseln für @code{LOAD DATA
INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.
@item -F, --flush-logs
Log-Datei im MySQL-Server zurückschreiben, bevor der Dump durchgeführt
wird.
@item -f, --force,
Fortfahren, selbst wenn beim Dump einer Tabelle ein SQL-Fehler auftritt.
@item -h, --host=..
Daten auf dem MySQL-Server auf dem genannten Host dumpen. Der
vorgabemäßige Host ist @code{localhost}.
@item -l, --lock-tables.
Alle Tabellen sperren, bevor mit dem Dump begonnen wird. Die Tabellen
werden mit @code{READ LOCAL} gesperrt, um gleichzeitiges Einfügen zu
erlauben (bei @code{MyISAM}-Tabellen).
@item -n, --no-create-db
'CREATE DATABASE /*!32312 IF NOT EXISTS*/ datenbank;' wird nicht in die
Ausgabe gschrieben. Diese Zeile wird ansonsten hinzugefügt, wenn
--databases oder --all-databases angegeben wurde.
@item -t, --no-create-info
Keine Tabellenerzeugungsinformation schreiben (das @code{CREATE
TABLE}-Statement).
@item -d, --no-data
Keine Zeileninformationen für die Tabelle schreiben. Das ist sehr
nützlich, wenn Sie lediglich einen Dump der Tabellenstruktur erzeugen
wollen.
@item --opt
Dasselbe wie @code{--quick --add-drop-table --add-locks --extended-insert
--lock-tables}. Das sollte den schnellstmöglichen Dump zum Einlesen in
einen MySQL-Server ergeben.
@item -pihr_passwort, --password[=ihr_passwort]
Das Passwort, das für die Verbindung zum Server benutzt werden soll. Wenn
Sie keinen @samp{=ihr_passwort}-Teil angeben, zeigt @code{mysqldump} eine
Eingabeaufforderung für Ihr Passwort.
@item -P port_num, --port=port_num
Die TCP/IP-Portnummer, die für die Verbindung zu einem Host benutzt werden
soll. (Diese wird für Verbindungen zu Hosts ausser @code{localhost}
benutzt, für den Unix-Sockets benutzt werden.)
@item  -q, --quick
Anfrage nicht puffern, sondern direkt zu stdout dumpen. Benutzt für die
Durchführung @code{mysql_use_result()}.
@item -r, --result-file=...
Direkte Ausgabe in die angegebene Datei. Diese Ausgabe sollte bei MS-DOS
benutzt werden, weil sie verhindert, dass das Zeichen für neue Zeile '\n'
in '\n\r' (new line + carriage return) umgewandelt werden.
@item -S /pfad/zu/socket, --socket=/pfad/zu/socket
Die Socket-Datei, die für die Verbindung zu @code{localhost} benutzt werden
soll (was der vorgabemäßige Host ist).
@item --tables
Überschreibt die Option --databases (-B).
@item  -T, --tab=pfad-zu-einem-verzeichnis
Erzeugt eine @code{tabelle.sql}-Datei, die die SQL-CREATE-Befehle enthält,
und eine @code{tabelle.txt}-Datei, die die Daten enthält, für jede
angegebene Tabelle. @strong{HINWEIS}: Das funktioniert nur, wenn
@code{mysqldump} auf derselben Maschine läuft wie der @code{mysqld}-Daemon.
Das Format der @code{.txt}-Datei hängt von den @code{--fields-xxx}- und
@code{--lines--xxx}-Optionen ab.
@item -u benutzername, --user=benutzername
Der MySQL-Benutzername, der für die Verbindung zum Server benutzt werden
soll. Der Vorgabewert ist Ihr Unix-Loginname. 
@item -O var=option, --set-variable var=option
Den Wert einer Variablen setzen. Die möglichen Werte sind unten aufgeführt.
@item -v, --verbose
Geschwätziger Modus. Gibt mehr Informationen darüber aus, was das Programm
tut.
@item -V, --version
Versionsinformationen ausgeben und beenden.
@item -w, --where='wo-bedingung'
Nur ausgewählte Datensätze dumpen. Beachten Sie, dass Anführungszeichen
zwingend erforderlich sind:

@example
"--where=user='jimf'" "-wuserid>1" "-wuserid<1"
@end example
@item -O net_buffer_length=#, where # < 16M
Beim Erzeugen von mehrzeiligen insert-Statements (wie bei der Option
@code{--extended-insert} oder @code{--opt}), erzeugt @code{mysqldump}
Zeilen bis zur Länge von @code{net_buffer_length}. Wenn Sie diesen Wert
herauf setzen, müssen Sie sicherstellen, dass die
@code{max_allowed_packet}-Variable im MySQL-Server größer als
@code{net_buffer_length} ist.
@end table

Der häufigste Gebrauch von @code{mysqldump} dient wahrscheinlich der
Herstellung einer Datensicherung ganzer Datenbanken. @xref{Backup}.

@example
mysqldump --opt datenbank > datensicherung.sql
@end example

Diese können Sie zurück in MySQL einlesen mit:

@example
mysql datenbank < datensicherung.sql
@end example

oder

@example
mysql -e "source /pfad-zur-datensicherung/datensicherung.sql" datenbank
@end example

Ausserdem ist es sehr nützlich, um einen anderen MySQL-Server mit
Informationen aus einer Datenbank zu füllen:

@example
mysqldump --opt datenbank | mysql ---host=entfernter-host -C datenbank
@end example

Es ist möglich, mehrere Datenbanken mit einem Befehl zu dumpen:

@example
mysqldump --databases datenbank1 [datenbank2 datenbank3...] > meine_datenbanken.sql
@end example

Wenn Sie alle Datenbanken dumpen wollen, benutzen Sie:

@example
mysqldump --all-databases > alle_datenbanken.sql
@end example


@node mysqlhotcopy, mysqlimport, mysqldump, Client-Side Scripts
@c German node mysqlhotcopy
@subsection mysqlhotcopy, MySQL-Datenbanken und Tabellen kopieren

@cindex dumpen, Datenbanken
@cindex Datenbanken, dumpen
@cindex Tabellen, dumpen
@cindex Datensicherung, Datenbanken

@code{mysqlhotcopy} ist a perl Skript that uses @code{LOCK TABLES},
@code{FLUSH TABLES} und @code{cp} oder @code{scp} to quickly make a backup
of a Datenbank.  It's the fastest way to make a backup of the Datenbank,
of single Tabellen but it can only be run on the same machine where the
Datenbankverzeichnisse are.

@example
mysqlhotcopy datenbank [/pfad/zu/new_Verzeichnis]

mysqlhotcopy datenbank_1 ... datenbank_n /pfad/zu/new_Verzeichnis

mysqlhotcopy datenbank./regex/
@end example

@code{mysqlhotcopy} unterstützt folgende Optionen:

@table @code
@item -?, --help
Hilfe ausgeben und beenden.
@item -u, --user=# 
Benutzername zum Einloggen.
@item -p, --password=#
Passwort für die Verbindung zum Server.
@item -P, --port=# 
Port zur Verbindung zum lokalen Server.
@item -S, --socket=#
Socket zur Verbindung zum lokalen Server.
@item --allowold
Nicht abbrechen, wenn das Ziel bereits existiert (sondern in _old umbenennen)
@item --keepold
Vorheriges (jetzt umbenanntes) Ziel nach dem Durchführen nicht löschen.
@item --noindices
Keine kompletten Index-Dateien in die Kopie einfügen, um die Datensicherung
kleiner und schneller zu machen. Die Indexe können später mit
@code{myisamchk -rq.} neu aufgebaut werden.
@item --method=#
Kopiermethode (@code{cp} oder @code{scp}).
@item -q, --quiet
Keine Meldungen ausgeben, ausser bei Fehlern.
@item --debug
Debug anschalten.
@item -n, --dryrun
Aktionen berichten, ohne sie auszuführen.
@item --regexp=#
Alle Datenbanken mit übereinstimmenden regexp-Namen sichern.
@item --suffix=#
Suffix für Namen kopierter Datenbanken.
@item --checkpoint=#
Checkpoint-Eingang in angegebene datenbank.tabelle einfügen.
@item --flushlog
Log-Dateien zurückschreiben, sobald alle Tabellen gesperrt sind.
@item --tmpdir=#
Temporäres Verzeichnis (anstelle von /tmp).
@end table

Geben Sie @code{perldoc mysqlhotcopy} ein, um eine vollständigere
Dokumentation von @code{mysqlhotcopy} zu erhalten.

@code{mysqlhotcopy} liest die Gruppen @code{[client]} und
@code{[mysqlhotcopy]} aus den Optionsdateien.

Damit Sie @code{mysqlhotcopy} ausführen können, benötigen Sie Schreibrechte
im Datensicherungsverzeichnis, @code{SELECT}-Berechtigung auf die Tabellen,
die Sie kopieren wollen, und die MySQL-@code{Reload}-Berechtigung (damit
Sie @code{FLUSH TABLES} ausführen können).


@node mysqlimport, mysqlshow, mysqlhotcopy, Client-Side Scripts
@c German node mysqlimport
@subsection mysqlimport, Daten aus Textdateien importieren

@cindex importieren, Daten
@cindex Daten, importieren
@cindex Dateien, Text-
@cindex Textdateien, importieren
@cindex @code{mysqlimport}

@code{mysqlimport} stellt eine Kommandozeilen-Schnittstelle für das
@code{LOAD DATA INFILE} SQL-Statement zur Verfügung. Die meisten Optionen
für @code{mysqlimport} entsprechen denselben Optionen für @code{LOAD DATA
INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.

@code{mysqlimport} wird wie folgt aufgerufen:

@example
shell> mysqlimport [optionen] datenbank textdatei1 [textdatei2....]
@end example

Bei jeder Textdatei, die auf der Kommandozeile angegeben wird, entfernt
@code{mysqlimport} jegliche Erweiterungen vom Dateinamen und benutzt das
Ergebnis, um festzulegen, in welche Tabelle der Dateiinhalt importiert
werden soll. Dateien namens @file{patient.txt}, @file{patient.text} und
@file{patient} beispielsweise würden alle in eine Tabelle namens
@code{patient} importiert werden.

@code{mysqlimport} unterstützt folgende Optionen:

@table @code
@item -c, --columns=...
Diese Option nimmt ein durch Kommas getrennte Auflistung von Feldnamen als
Argument entgegen. Die Feldliste wird benutzt, um einen korrekten
@code{LOAD DATA INFILE}-Befehl zu erzeugen, der an MySQL durchgereicht
wird. @xref{LOAD DATA, , @code{LOAD DATA}}.

@item -C, --compress
Komprimiert alle Informationen zwischen Client und Server, wenn bei
Kompression unterstützen.

@item -#, --debug[=option_string]
Programmbenutzung tracen (zum Debuggen).

@item -d, --delete
Tabelle leeren, bevor die Textdatei importiert wird.

@item --fields-terminated-by=...
@itemx --fields-enclosed-by=...
@itemx --fields-optionally-enclosed-by=...
@itemx --fields-escaped-by=...
@itemx --lines-terminated-by=...
Diese Optionen haben dieselbe Bedeutung wie die entsprechenden Klauseln für
@code{LOAD DATA INFILE}. @xref{LOAD DATA, , @code{LOAD DATA}}.

@item -f, --force
Fehler ignorieren. Wenn beispielsweise eine Tabelle für eine Textdatei
nicht existiert, mit den verbleibenden Dateien weitermachen. Ohne
@code{--force} wird @code{mysqlimport} beendet, wenn die Tabelle nicht
existiert.

@item --help
Hilfetext ausgeben und beenden.

@item -h host_name, --host=host_name
Daten in den MySQL-Server auf dem genannten Host importieren. Der
vorgabemäßige Host ist @code{localhost}.

@item -i, --ignore
Siehe Beschreibung für die @code{--replace}-Option.

@item -l, --lock-tables
@strong{ALLE} Tabellen für Schreibvorgänge sperren, bevor irgend welche
Textdateien verarbeitet werden. Das stellt sich, dass alle Tabellen auf dem
Server synchronisiert werden.

@item -L, --local
Liest Eingabedateien vom Client. Vorgabemäßig wird angenommen, dass
Textdateien auf dem Server liegen, wenn Sie sich über @code{localhost}
verbinden (was der vorgabemäßige Host ist).

@item -pihr_passwort, --password[=ihr_passwort]
Das Passwort, das für die Verbindung zum Server benutzt werden soll. Wenn
Sie keinen @samp{=ihr_passwort}-Teil angeben, zeigt @code{mysqlimport}
eine Eingabeaufforderung für Ihr Passwort.

@item -P port_num, --port=port_num
Die TCP/IP-Portnummer, die für die Verbindung zu einem Host benutzt werden
soll. (Diese wird für Verbindungen zu Hosts ausser @code{localhost}
benutzt, für den Unix-Sockets benutzt werden.)

@item -r, --replace
Die @code{--replace}- und @code{--ignore}-Optionen steuern die Handhabung
von Eingabe-Datensätzen, die bestehende Datensätze auf eindeutigen
Schlüsseln duplizieren würden. Wenn Sie @code{--replace} angeben, werden
bestehende Zeilen ersetzt, die denselben eindeutigen Schlüsselwert
besitzen. Wenn Sie @code{--ignore} angeben, werden Zeilen, die eine
bestehende Zeile duplizieren würden, übersprungen. Wenn Sie keine der
beiden Optionen angeben, tritt ein Fehler auf, wenn ein doppelter
Schlüsseleintrag gefunden wird, und der Rest der Textdatei wird ignoriert.

@item  -s, --silent
Schweigsamer Modus.  Ausgaben erfolgen nur, wenn Fehler auftreten.

@item -S /pfad/zu/socket, --socket=/pfad/zu/socket
Die Socket-Datei, die für die Verbindung zu @code{localhost} benutzt werden
soll (der der vorgabemäßige Host ist).

@item -u benutzername, --user=benutzername
Der MySQL-Benutzername, der für die Verbindung zum Server benutzt werden
soll. Der Vorgabewert ist Ihr Unix-Loginname.

@item -v, --verbose
Geschwätziger Modus. Mehr Informationen darüber ausgeben, was das Programm
macht.

@item -V, --version
Versionsinformationen ausgeben und beenden.
@end table

Hier ist ein Beispiel für die Benutzung von @code{mysqlimport}:

@example
$ mysql --version
mysql  Ver 9.33 Distrib 3.22.25, for pc-linux-gnu (i686)
$ uname -a
Linux xxx.com 2.2.5-15 #1 Mon Apr 19 22:21:09 EDT 1999 i586 unknown
$ mysql -e 'CREATE TABLE imptest(id INT, n VARCHAR(30))' test
$ ed
a
100     Max Sydow
101     Graf Dracula
.
w imptest.txt
32
q
$ od -c imptest.txt
0000000   1   0   0  \t   M   a   x       S   y   d   o   w  \n   1   0
0000020   1  \t   G r a f       D   r   a   c   u   l   a  \n
0000040
$ mysqlimport --local test imptest.txt
test.imptest: Records: 2  Deleted: 0  Skipped: 0  Warnings: 0
$ mysql -e 'SELECT * FROM imptest' test
+------+---------------+
| id   | n             |
+------+---------------+
|  100 | Max Sydow     |
|  101 | Graf Dracula  |
+------+---------------+
@end example


@node mysqlshow, perror, mysqlimport, Client-Side Scripts
@c German node mysqlshow
@subsection Datenbanken, Tabellen und Spalten anzeigen

@cindex Datenbanken, anzeigen
@cindex anzeigen, Datenbankinformationen
@cindex Tabellen, anzeigen
@cindex Spalten, anzeigen
@cindex Anzeigen, Datenbankinformationen

@code{mysqlshow} wird benutzt, um schnell nachzusehen, welche Datenbanken,
Tabellen und Tabellenspalten es gibt.

Mit dem @code{mysql}-Programm können Sie dieselben Information mit den
@code{SHOW}-Befehlen erhalten. @xref{SHOW}.

@code{mysqlshow} wird wie folgt aufgerufen:

@example
shell> mysqlshow [optionen] [datenbank [tabelle [spalte]]]
@end example

@itemize @bullet
@item
Wenn keine Datenbank angegeben wird, werden alle passenden Datenbanken
gezeigt.
@item
Wenn keine Tabelle angegeben wird, werden alle passenden Tabellen in der
Datenbank gezeigt.
@item
Wenn keine Spalte angegeben wird, werden alle passenden Spalten und
Spaltentypen in der Tabelle gezeigt.
@end itemize

Beachten Sie, dass Sie in neueren MySQL-Versionen nur die Datenbanken,
Tabellen und Spalten sehen können, für die Sie irgend welche Berechtigungen
haben.

Wenn das letzte Argument einen Shell- oder SQL-Platzhalter enthält
(@code{*}, @code{?}, @code{%} oder @code{_}), wird nur das gezeigt, was dem
Platzhalter entspricht. Das kann zu Verwirrung führen, wenn Sie Spalten
einer Tabelle anzeigen, die einen Unterstrich (@code{_}) enthalten, weil
Ihnen @code{mysqlshow} in diesem Fall nur die Tabellennamen zeigt, die dem
Muster entsprechen. Das kann leicht durch Hinzufügen eines zusätzlichen
@code{%} am Ende der Kommandozeile (als separates Argument) behoben werden.


@node perror, Batch Commands, mysqlshow, Client-Side Scripts
@c German node perror
@subsection perror, Erklärung der Fehler-Codes

@cindex Fehlermeldungen, anzeigen
@cindex perror

@code{perror} wird benutzt, um Fehlermeldungen auszugeben. @code{perror}
wird wie folgt aufgerufen:

@example
shell> perror [optionen] [ERRORCODE [ERRORCODE...]]

For example:

shell> perror 64 79
Error code  64:  Machine ist not on the network
Error code  79:  Can not access a needed shared library
@end example

@code{perror} wird benutzt, um eine Beschreibung für einen
Systemfehler-Code anzuzeigen, oder einen Fehler-Code des
MyISAM/ISAM-Tabellen-Handlers. Die Fehlermeldungen sind hauptsächlich
abhängig vom Betriebssystem.


@node Batch Commands,  , perror, Client-Side Scripts
@c German node Stapelbefehle
@subsection Wie SQL-Befehle aus einer Textdatei laufen gelassen werden

@c FIX add the 'source' befehl

Der @code{mysql}-Client wird typischerweise interaktiv benutzt, wie folgt:

@example
shell> mysql datenbank
@end example

Es ist jedoch möglich, Ihre SQL-Befehle in eine Datei zu schreiben und
@code{mysql} anzuweisen, ihre Eingaben aus dieser Datei zu lesen. Um das zu
tun, erzeugen Sie eine Textdatei @file{textdatei}, die die Befehle enthält,
die Sie ausführen wollen. Dann rufen Sie @code{mysql} wie gezeigt auf:

@example
shell> mysql datenbank < textdatei
@end example

Sie können Ihre Textdatei auch mit einem @code{USE datenbank}-Statement
beginnen lassen. In diesem Fall ist es nicht notwendig, den Datenbanknamen
auf der Kommandozeile anzugeben:

@example
shell> mysql < textdatei
@end example

@xref{Client-Side Scripts}.


@node Log Files, Replication, Client-Side Scripts, MySQL Database Administration
@c German node Log-Dateien
@section Die MySQL-Log-Dateien

@cindex Log-Dateien

MySQL hat mehrere unterschiedliche Log-Dateien, die Ihnen helfen können
herauszufinden, was innerhalb @code{mysqld} vor sich geht:

@multitable @columnfractions .3 .7
@item Die Fehler-Log-Datei @tab Probleme, die beim Start, beim Laufenlassen oder beim Anhalten von @code{mysqld} auftreten.
@item Die ISAM-Log-Datei @tab Loggt alle Änderungen in ISAM-Tabellen mit. Wird nur benutzt, um den ISAM-Code zu debuggen.
@item Die Anfragen-Log-Datei @tab Hergestellte Verbindungen und ausgeführte Anfragen.
@item Die Update-Log-Datei @tab Veraltet: Speichert Statements, die Daten verändern.
@item Die Binär-Log-Datei @tab Speichert alle Statements, die etwas ändern. Wird auch für Replikation benutzt.
@item Die Slow-Log-Datei @tab Speichert alle Anfragen, die länger als @code{long_query_time} zur Ausführung benötigten oder keine Indexe benutzten.
@end multitable

Alle Log-Dateien liegen im @code{mysqld} Daten-Verzeichnis. Sie können
@code{mysqld} zwingen, die Log-Dateien neu zu öffnen (oder in manchen
Fällen auf eine neue Log-Datei umzuschalten), indem Sie @code{FLUSH LOGS}
ausführen. @xref{FLUSH}.



@menu
* Error log::                   
* Query log::                   
* Update log::                  
* Binary log::                  
* Slow query log::              
* Log file maintenance::        
@end menu

@node Error log, Query log, Log Files, Log Files
@c German node Fehler-Log-Datei
@subsection Die Fehler-Log-Datei

@code{mysqld} schreibt alle Fehler nach stderr, die das
@code{safe_mysqld}-Skript in eine Datei namens @code{'hostname'.err}
umleitet. (Unter Windows schreibt @code{mysqld} direkt in die Datei
@file{\mysql\data\mysql.err}.)

Diese enthält Informationen, wann @code{mysqld} gestartet und angehalten
wurde und zusätzlich jeden kritischen Fehler, der während der Laufzeit
passierte. Wenn @code{mysqld} unerwartet stirbt und @code{safe_mysqld} ihn
neu starten muss, schreibt @code{safe_mysqld} eine @code{restarted
mysqld}-Zeile in diese Datei. Diese Log-Datei enthält auch Warnungen, wenn
@code{mysqld} eine Tabelle bemerkt, die automatisch geprüft oder repariert
werden muss.

Auf manchen Betriebssystemen enthält die Fehler-Log-Datei einen
Stack-Trace, wo @code{mysqld} starb. Dieser kann benutzt werden, um
herauszufinden, wo @code{mysqld} starb. @xref{Using stack trace}.


@node Query log, Update log, Error log, Log Files
@c German node Anfragen-Log-Datei
@subsection Die allgemeine Anfragen-Log-Datei

@cindex Anfragen-Log-Datei
@cindex Dateien, Anfragen-Log-Datei

Wenn Sie wissen wollen, was innerhalb @code{mysqld} geschieht, sollten Sie
ihn mit @code{--log[=file]} starten. Diese Option loggt alle Verbindungen
und Anfragen in die Log-Datei (vorgabemäßig @file{'hostname'.log}
benannt). Diese Log-Datei kann sehr nützlich sein, wenn Sie einen Fehler in
einem Client vermuten und wissen wollen, was genau @code{mysqld} sich bei
dem dachte, was es vom Client geschickt bekam.

Vorgabemäßig startet das @code{mysql.server}-Skript den MySQL-Server mit
der @code{-l}-Option. Wenn Sie bessere Performance brauchen, wenn Sie MySQL
in einer Produktionsumgebung starten, können Sie die @code{-l}-Option aus
@code{mysql.server} entfernen oder sie zu @code{--log-binary} ändern.

Die Einträge in diese Log-Datei werden geschrieben, wenn @code{mysqld} die
Anfragen erhält. Die Reihenfolge kann vor derjenigen abweichen, in der die
Statements ausgeführt werden. Das steht im Gegensatz zur Update-Log-Datei
und zur Binär-Log-Datei, bei denen geschrieben wird, nachdem die Anfrage
ausgeführt wurde, aber bevor irgend welche Sperren aufgehoben werden.


@node Update log, Binary log, Query log, Log Files
@c German node Update-Log-Datei
@subsection Die Update-Log-Datei

@cindex Update-Log-Datei
@cindex Dateien, Update-Log-Datei

@strong{HINWEIS}: Die Update-Log-Datei wird durch die binäre Log-Datei
ersetzt. @xref{Binary log}. Mit dieser können Sie alles machen, was
Sie mit der Update-Log-Datei machen können.

Wenn er mit der @code{--log-update[=datei]}-Option gestartet wird, schreibt
@code{mysqld} eine Log-Datei, die alle SQL-Befehle enthält, die Daten
aktualisieren. Wenn kein Dateiname angegeben wird, ist die Vorgabe der Name
der Host-Maschine. Wenn ein Dateiname angegeben wird, der aber keine
Pfadangabe enthält, wird die Datei ins Daten-Verzeichnis geschrieben. Wenn
@file{datei} keine Erweiterung hat, erzeugt @code{mysqld} eine Log-Datei,
die er wie folgt benennt: @file{datei.###}, wobei @code{###} eine Zahl ist,
die jedes Mal hochgezählt wird, wenn Sie @code{mysqladmin refresh} oder
@code{mysqladmin flush-logs} oder das @code{FLUSH LOGS}-Statement
ausführen, oder wenn Sie den Server neu starten.

@strong{HINWEIS:} Damit das dargestellte Schema funktioniert, sollten Sie
NICHT eigene Dateien mit demselben Dateinamen wie die Update-Log-Datei plus
Erweiterungen, die als die hochgezählte Zahl betrachtet werden könnten, im
Verzeichnis anlegen, das von der Update-Log-Datei benutzt wird!

Wenn Sie die @code{--log} oder @code{-l}-Optionen benutzen, schreibt
@code{mysqld} eine allgemeine Log-Datei mit dem Dateinamen
@file{hostname.log}. Neustarts und Refresh-Operationen führen dann nicht
dazu, dass eine neue Log-Datei erzeugt wird (obwohl diese geschlossen und
wieder geöffnet wird). In diesem Fall können Sie sie (unter Unix) wie folgt
kopieren:

@example
mv hostname.log hostname-old.log
mysqladmin flush-logs
cp hostname-old.log ins-datensicherungs-verzeichnis
rm hostname-old.log
@end example

Das Mitloggen mittels der Update-Log-Datei ist clever, weil es nur
Statements loggt, die tatsächlich Daten aktualisieren. Wenn ein
@code{UPDATE} oder ein @code{DELETE} mit einem @code{WHERE} keine passenden
Zeilen findet, wird nichts in die Log-Datei geschrieben. Es werden sogar
@code{UPDATE}-Statements übersprungen, die eine Spalte auf einen Wert
setzen, die sie bereits hat.

Das Schreiben in die Update-Log-Datei wird unmittelbar durchgeführt,
nachdem eine Anfrage fertig ist, aber bevor irgend welche Sperren
aufgehoben sind oder irgendein Commit durchgeführt wurde. Das stellt
sicher, dass die Log-Datei stets in der Reihenfolge der Ausführung
mitschreibt.

Wenn Sie eine Datenbank von Update-Log-Datei-Dateien aktualisieren wollen,
könnten Sie folgendes tun (angenommen, Ihre Update-Log-Dateien haben Namen
der Form @file{datei.###}):

@example
shell> ls -1 -t -r datei.[0-9]* | xargs cat | mysql
@end example

@code{ls} wird benutzt, um alle Log-Dateien in der richtigen Reihenfolge zu
erhalten.

Das ist nützlich, wenn Sie Datensicherungsdateien nach einem Absturz
zurückspielen müssen und die Aktualisierungen neu ausführen wollen, die
zwischen der Zeit der Datensicherung und dem Absturz lagen.


@node Binary log, Slow query log, Update log, Log Files
@c German node Binär-Log-Datei
@subsection Die binäre Update-Log-Datei

@cindex Binär-Log-Datei
@cindex Dateien, Binär-Log-Datei

In Zukunft wird die Binär-Log-Datei die Update-Log-Datei ersetzen, daher
empfehlen wir, dass Sie so bald wie möglich zu diesem Log-Format wechseln!

Die Binär-Log-Datei enthält alle Informationen, die im Update-Log verfügbar
sind, in einem effizienteren Format. Sie enthält ausserdem Informationen
darüber, wie lange jede Anfrage brauchte, die die Datenbank aktualisierte.

Die Binär-Log-Datei wird auch benutzt, wenn Sie einen Slave von einem
Master replizieren. @xref{Replication}.

Mit der @code{--log-bin[=datei]}-Option gestartet, schreibt @code{mysqld}
eine Log-Datei, die alle SQL-Befehle enthält, die Daten aktualisieren. Wenn
kein Dateiname angegeben wird, ist die Vorgabe der Name der Host-Machine,
gefolgt von @code{-bin}. Wenn der Dateiname angegeben wird, aber keine
Pfadangabe enthält, wird die Datei ins Daten-Verzeichnis geschrieben.

Sie können folgende Optionen für @code{mysqld} benutzen, um zu
beeinflussen, was in die Binär-Log-Datei geschrieben wird:

@multitable @columnfractions .4 .6
@item @code{binlog-do-db=datenbank} @tab
Weist den Master an, Aktualisierungen für die angegebene Datenbank zu
loggen und alle anderen, nicht explizit erwähnten, auszuschließen.
(Beispiel: @code{binlog-do-db=eine_datenbank})

@item @code{binlog-ignore-db=datenbank} @tab
Weist den Master an, Aktualisierungen für die angegebene Datenbank nicht in
die Binär-Log-Datei zu loggen (Beispiel:
@code{binlog-ignore-db=eine_datenbank}).
@end multitable

@code{mysqld} hängt dem Binär-Log-Datei-Dateinamen eine Erweiterung an, die
eine Zahl ist, die jedes Mal heraufgezählt wird, wenn Sie @code{mysqladmin
refresh}, @code{mysqladmin flush-logs} oder ein @code{FLUSH LOGS}-Statement
ausführen oder den Server neu starten.

Damit Sie feststellen können, welche verschiedenen Binär-Log-Datei-Dateien
benutzt wurden, erzeugt @code{mysqld} auch eine Binär-Log-Index-Datei, die
die Namen aller benutzten Binär-Log-Datei-Dateien enthält. Vorgabemäßig
hat diese denselben Namen wie die Binär-Log-Datei, mit der Erweiterung
@code{'.index'}. Sie können den Namen der Binär-Log-Index-Datei mit der
@code{--log-bin-index=[filename]}-Option ändern.

Wenn Sie Replikation benutzen, sollten Sie keine alten Binär-Log-Dateien
löschen, bis Sie sicher sind, dass kein Slave sie jemals wieder benötigen
wird. Eine Art, das zu tun, ist, einmal pro Tag @code{mysqladmin
flush-logs} auszuführen, und danach alle Logs zu entfernen, die älter als 3
Tage sind.

Sie können die Binär-Log-Datei mit dem @code{mysqlbinlog}-Befehl
untersuchen. Beispielsweise können Sie einen MySQL-Server wie folgt aus der
Binär-Log-Datei aktualisieren:

@example
mysqlbinlog log-file | mysql -h server_name
@end example

Sie können auch das @code{mysqlbinlog}-Programm benutzen, um die
Binär-Log-Datei direkt von einem entfernten MySQL-Server zu lesen!

@code{mysqlbinlog --help} gibt Ihnen weitere Informationen zur Benutzung
dieses Programms.

Wenn Sie @code{BEGIN [WORK]} oder @code{SET AUTOCOMMIT=0} verwenden, müssen
Sie die MySQL-Binär-Log-Datei für Datensicherungen anstelle der alten
Update-Log-Datei benutzen.

Das Loggen in die Binär-Log-Datei wird unmittelbar nach jeder Anfrage
geschrieben, aber bevor irgend welche Sperren aufgehoben wurden oder irgend
ein Commit durchgeführt wurde. Das stellt sicher, dass die Log-Datei in der
Reihenfolge der Ausführung mitschreibt.

Alle Aktualisierungen (@code{UPDATE}, @code{DELETE} oder @code{INSERT}),
die eine transaktionale Tabelle (like BDB-Tabellen) ändern, werden bis zu
einem @code{COMMIT} gecachet. Jegliche Aktualisierungen auf eine nicht
transaktionale Tabelle werden sofort in der Binär-Log-Datei gespeichert.
Jedem Thread wird beim Start ein Puffer der Größe @code{binlog_cache_size}
für die Pufferung von Anfragen zugewiesen. Wenn eine Anfrage größer als
dieser ist, öffnet der Thread eine temporäre Datei, um den größeren Cache
zu handhaben. Die temporäre Datei wird gelöscht, wenn der Thread beendet
wird.

@code{max_binlog_cache_size} kann dazu benutzt werden, um die gesamte
benutzte Größe zu begrenzen, und um eine Anfrage aus mehreren
Transaktionen zu cachen.

Wenn Sie die Update- oder Binär-Log-Datei benutzen, funktionieren
gleichzeitige Einfügeoperationen nicht im Zusammenhang mit @code{CREATE ...
INSERT} und @code{INSERT ... SELECT}. Damit stellen Sie sicher, dass Sie
eine exakte Kopie Ihrer Tabellen wieder herstellen können, indem Sie die
Log-Datei auf eine Datensicherung anwenden.


@node Slow query log, Log file maintenance, Binary log, Log Files
@c German node Langsame-Anfragen-Log-Datei
@subsection Die Anfragen-Log-Datei für langsame Anfragen

@cindex Langsame-Anfragen-Log-Datei
@cindex Dateien, Langsame-Anfragen-Log-Datei

Mit der @code{--log-slow-queries[=datei]}-Option gestartet schreibt
@code{mysqld} eine Log-Datei, die alle SQL-Befehle enthält, die länger als
@code{long_query_time} zur Ausführung brauchten. Die Zeit, um die
anfänglichen Tabellensperren zu erhalten, wird nicht zur Ausführungszeit
hinzugezählt.

Anfragen-Log-Datei für langsame Anfragen wird geschrieben, nachdem jede
Anfrage ausgeführt wurde und nachdem alle Sperren aufgehoben wurden. Das
kann von der Reihenfolge abweichen, in der die Statements ausgeführt
wurden.

Wenn kein Dateiname angegeben wird, ist die Vorgabe der Name der
Host-Maschine mit dem Suffix @code{-slow.log}. Wenn ein Dateiname angegeben
wird, der aber keine Pfadangabe enthält, wird die Datei ins Daten-Verzeichnis geschrieben. 

Die Anfragen-Log-Datei für langsame Anfragen kann benutzt werden, um
Anfragen zu finden, die für die Ausführung lange Zeit benötigen und daher
Kandidaten für Optimierungen sind, was bei einer großen Log-Datei
allerdings eine schwierige Aufgabe werden kann. Sie können die
Anfragen-Log-Datei für langsame Anfragen durch den
@code{mysqldumpslow}-Befehl durchschleifen (pipen), um eine Zusammenfassung
der Anfragen zu erhalten, die in der Log-Datei erscheinen.

Wenn Sie @code{--log-long-format} benutzen, erscheinen auch Anfragen, die
keine Indexe benutzen. @xref{Command-line options}.


@node Log file maintenance,  , Slow query log, Log Files
@c German node Log-Datei-Wartung
@subsection Wartung und Pflege der Log-Dateien

@cindex Dateien, Log-Dateien
@cindex Wartung, Log-Dateien
@cindex Log-Dateien, Wartung

MySQL hat viele Log-Dateien, die es leicht machen festzustellen, was vor
sich geht. @xref{Log Files}. Von Zeit zu Zeit jedoch muss man hinter
@code{MySQL} saubermachen, damit die Log-Dateien nicht zu viel
Festplattenplatz in Anspruch nehmen.

Wenn Sie MySQL mit Log-Dateien benutzen, werden Sie von Zeit zu Zeit alte
Log-Dateien entfernen wollen und MySQL mitteilen, in neue Dateien zu
loggen. @xref{Backup}.

Bei einer Linux-(@code{RedHat})-Installation können Sie hierfür das
@code{mysql-log-rotate}-Skript benutzen. Wenn Sie MySQL von einer
RPM-Distribution installiert haben, sollte das Skript automatisch
installiert worden sein. Beachten Sie, dass Sie damit vorsichtig umgehen
sollten, wenn Sie die Log-Datei für Replikation benutzen!

Auf anderen Systemen müssen Sie selbst ein kurzes Skript installieren, dass
Sie von @code{cron} starten können, um Log-Dateien zu handhaben.

Sie können MySQL zwingen, mit neuen Log-Dateien zu starten, indem Sie
@code{mysqladmin flush-logs} oder den SQL-Befehl @code{FLUSH LOGS}
benutzen. Wenn Sie MySQL-Version 3.21 benutzen, müssen Sie @code{mysqladmin
refresh} benutzen.

Der obige Befehl macht folgendes:

@itemize @bullet
@item
Wenn standardmäßiges Loggen (@code{--log}) oder Loggen langsamer Anfragen
(@code{--log-slow-queries}) benutzt wird, wird die Log-Datei geschlossen
und wieder geöffnet (@file{mysql.log} und @file{`hostname`-slow.log} als
Vorgabe).
@item
Wenn Update-Logging (@code{--log-update}) benutzt wird, wird die
Update-Log-Datei geschlossen und eine neue Log-Datei mit einer höheren
Log-Zahl geöffnet.
@end itemize

Wenn Sie nur eine Update-Log-Datei benutzen, müssen Sie die Log-Dateien nur
auf Platte zurückschreiben (flush) und dann die alten
Update-Log-Datei-Dateien zu einer Datensicherungsdatei verschieben. Wenn
Sie normales Loggen benutzen, können Sie etwas wie das Folgende tun:

@example
shell> cd mysql-data-verzeichnis
shell> mv mysql.log mysql.old
shell> mysqladmin flush-logs
@end example

Und dann eine Datensicherung nehmen und @file{mysql.old} entfernen.


@node Replication,  , Log Files, MySQL Database Administration
@c German node Replikation
@section Replikation bei MySQL

@cindex Replikation
@cindex erhöhen, Geschwindigkeit
@cindex Geschwindigkeit, erhöhen
@cindex Datenbanken, replizieren


Dieses Kapitel beschreibt die verschiedenen Replikationsfeatures in MySQL.
Es dient als Referenz für die Optionen, die bei Replikation verfügbar sind.
Sie erhalten eine Einführung in die Replikation und lernen, wie Sie sie
implementieren. Am Ende des Kapitels werden einige häufige gestellte Fragen
und die dazugehörigen Antworten aufgelistet sowie Beschreibungen der
Probleme und wie man sie löst.


@menu
* Replication Intro::           
* Replication Implementation::  
* Replication HOWTO::           
* Replication Features::        
* Replication Options::         
* Replication SQL::             
* Replication FAQ::             
* Replication Problems::        
@end menu

@node Replication Intro, Replication Implementation, Replication, Replication
@c German node Einführung in die Replikation
@subsection Einführung in die Replikation

Einweg-Replikation wird benutzt, um sowohl Stabilität als auch
Geschwindigkeit zu steigern. Was Stabilität betrifft, haben Sie zwei
Möglichkeiten und können zur Möglichkeit der Datensicherung zurückkehren,
wenn Sie Probleme mit dem Master haben. Die Geschwindigkeitssteigerung wird
dadurch erreicht, dass ein Teil der Anfragen, die nichts aktualisieren, an
den Replikationsserver geschickt werden. Das funktioniert naturgemäß nur
dann, wenn Anfragen, die nichts aktualisieren, überwiegen, aber das ist der
Normalfall.

@c German FIX changes @xref to @pxref (because it's in parenthesis).
Ab Version 3.23.15 unterstützt MySQL intern Einweg-Replikation. Ein Server
agiert als Master, der andere als Slave. Beachten Sie, dass ein Server
beide Rolle - als Master und als Slave - in einem Paar spielen kann. Der
Master hält eine Binär-Log-Datei der Aktualisierungen vor
(@pxref{Binary log}) sowie eine Index-Datei für Binär-Log-Dateien, um
hinsichtlich der Log-Rotation auf dem Laufenden zu bleiben. Der Slave
informiert den Master beim Verbinden darüber, wo er seit der letzten
erfolgreich durchgeführten Aktualisierung aufgehört hat, schließt zu den
Aktualisierungen auf, blockiert danach und wartet darauf, dass ihn der
Master über neue Aktualisierungen informiert.

Beachten Sie, dass alle Aktualisierungen auf eine Datenbank, die repliziert
wird, durch den Master durchgeführt werden sollten!

Ein weiterer Vorteil von Replikation ist, dass man permanente (live)
Datensicherungen vom System erhält, wenn man die Datensicherung auf dem
Slave durchführt statt auf dem Master. @xref{Backup}.


@node Replication Implementation, Replication HOWTO, Replication Intro, Replication
@c German node Replikationsimplementation
@subsection Replikationsimplementation

@cindex Master-Slave-Einrichtung

@c German FIX changes @xref to @pxref (because it's in parenthesis).
MySQL-Replikation basiert darauf, dass der Server alle Änderungen Ihrer
Datenbank im Binär-Log verfolgt (Updates, Deletes usw.)
(@pxref{Binary log}) und der oder die Slave-Server die gespeicherten
Anfragen aus der Binär-Log-Datei des Masters lesen, so dass der Slave
dieselben Anfragen auf seine Kopie der Daten ausführen kann.

Es ist @strong{sehr wichtig} sich klarzumachen, dass die Binär-Log-Datei
schlicht eine Aufzeichnung ist, die ab einem festen Zeitpunkt an startet
(ab dem Moment, wo Sie Binär-Loggen starten). Alle Slaves, die Sie
aufsetzen, benötigen Kopien aller Daten vom Master, wie Sie zu dem
Zeitpunkt existierten, als Binär-Loggen auf dem Master aktiviert wurde.
Wenn Sie Ihre Slaves mit Daten starten, die nicht mit dem übereinstimmen,
was auf dem Master war, @strong{als die Binär-Log-Datei gestartet wurde},
funktionieren Ihre Slaves womöglich nicht richtig.

Eine zukünftige Version (4.0) von MySQL wird die Notwendigkeit beseitigen,
(eventuell große) Schnappschüsse von Daten für neue Slaves vorzuhalten,
die Sie über die Live-Datensicherungs-Funktionalität aufsetzen wollen,
wobei kein Sperren (Locking) erforderlich ist. Zu dieser Zeit ist es jedoch
notwendig, alle Schreibzugriffe entweder mit einer globalen Lese-Sperre
oder durch das Herunterfahren des Masters zu blockieren, während man einen
Schnappschuss anlegt.

Sobald ein Slave korrekt konfiguriert ist und läuft, verbindet er sich
einfach mit dem Master und wartet darauf, dass Aktualisierung ausgeführt
werden. Wenn der Master abgeschaltet wird oder der Slave die Verbindung zum
Master verliert, versucht er alle @code{master-connect-retry} Sekunden,
sich neu zu verbinden, bis er sich neu verbinden kann, und nimmt dann das
Warten auf Aktualisierungen wieder auf.

Jeder Slave achtet darauf, wo er aufgehört hat. Der Master-Server weiß
nicht, wie viele Slaves es gibt oder welche zu einem gegebenen Zeitpunkt
auf aktuellem Stand sind.

Der nächste Abschnitt erläutert den Master-Slave-Einrichtungsprozess
detaillierter.


@node Replication HOWTO, Replication Features, Replication Implementation, Replication
@c German node Wie man Replikation aufsetzt
@subsection Wie man Replikation aufsetzt

Unten findet sich eine kurze Beschreibung, wie Sie komplette Replikation
auf Ihrem aktuellen MySQL-Server einrichten können. Es wird angenommen,
dass Sie alle Ihre Datenbanken replizieren wollen und bislang Replikation
noch nicht konfiguriert haben. Sie müssen Ihren Master-Server kurz herunter
fahren, um die unten stehenden Schritte fertigzustellen.

@enumerate
@item
Stellen Sie sicher, dass Sie eine aktuelle Version von MySQL auf dem Master
und dem Slave oder den Slaves haben.

Benutzen Sie Version 3.23.29 oder höher. Vorherige Releases benutzten ein
anderes Binär-Log-Format und hatten Bugs, die in neueren Releases behoben
wurden. Bitte berichten Sie keine Bugs, bevor Sie bestätigen können, dass
das Problem im neuesten Release beobachtet werden kann.

@item
Richten Sie einen speziellen Replikationsbenutzer auf dem Master mit der
@code{FILE}-Berechtigung und Berechtigungen, sich von allen Slaves aus zu
verbinden, ein. Wenn der Benutzer ausschließlich Replikation durchführt
(was empfohlen wird), müssen Sie ihm keine zusätzlichen Berechtigungen
geben.

Erzeugen Sie zum Beispiel einen Benutzer namens @code{repl}, der auf Ihren
Master von jedem Host aus zugreifen kann, mit folgendem Befehl:

@example
GRANT FILE ON *.* TO repl@@"%" IDENTIFIED BY 'passwort';
@end example

@item
Fahren Sie den MySQL-Master herunter:

@example
mysqladmin -u root -ppasswort shutdown
@end example

@item
Machen Sie einen Schnappschuss aller Daten auf Ihrem Master-Server.

Die einfachste Art, das (unter Unix) zu tun, ist, einfach @strong{tar} zu
benutzen, um ein Archiv Ihre gesamten Daten-Verzeichnisses zu erzeugen. Der
genaue Speicherort Ihres Daten-Verzeichnisses hängt von Ihrer Installation
ab.

@example
tar -cvf /tmp/mysql-snapshot.tar /pfad/zu/data-dir
@end example

Windows-Benutzer können WinZip oder ähnliche Software benutzen, um ein
Archiv des Daten-Verzeichnisses anzulegen.

@item
In der Datei @code{my.cnf} für den Master fügen Sie @code{log-bin} und
@code{server-id=eindeutige_nummer} zum @code{[mysqld]}-Abschnitt und hinzu
und starten Sie den Server neu. Es ist sehr wichtig, dass die ID auf dem
Slave sich von der ID auf dem Master unterscheidet. Denken Sie sich
@code{server-id} als etwas, dass einer IP-Adresse ähnlich ist - es
identifiziert in der Gemeinschaft der Replikationspartner die
Server-Instanz eindeutig.

@example
[mysqld]
log-bin
server-id=1
@end example

@item
Starten Sie den MySQL-Master neu.

@item
Fügen Sie auf dem Slave oder den Slaves folgendes zur Datei
@code{my.cnf} hinzu:

@example
master-host=hostname_des_masters
master-user=replikations_benutzername
master-password=replikations_benutzerpasswort
master-port=TCP/IP-Port_für_master>
server-id=eine_eindeutige_nummer_zwischen_2_und_2^32-1
@end example

Ersetzen Sie die Beispielwerte durch etwas, was für Ihr System stimmig ist.

@code{server-id} muss für jeden Partner, der an Replikation teilnimmt,
unterschiedlich sein. Wenn Sie keine server-id angeben, wird sie auf 1
gesetzt, falls Sie @code{master-host} nicht definiert haben, ansonsten wird
sie auf 2 gesetzt. Beachten Sie für den Fall, dass sie @code{server-id}
weglassen, dass der Master Verbindungen von allen Slaves verweigert und die
Slaves verweigern werden, sich mit dem Master zu verbinden. Daher ist das
Weglassen der @code{server-id} nur dann eine gute Idee, wenn Sie es nur für
Datensicherungen mit einer Binär-Log-Datei verwenden.


@item
Kopieren Sie die Schnappschuss-Daten in Ihr Daten-Verzeichnis auf Ihrem
Slave oder Ihren Slaves. Stellen Sie sicher, dass die Berechtigungen auf
die Dateien und Verzeichnisse korrekt sind. Der Benutzer, unter dem MySQL
läuft, muss in der Lage sein, sie zu lesen und zu schreiben, genau wie auf
dem Master.

@item Starten Sie den Slave oder die Slaves neu.

@end enumerate

Nachdem Sie das Obige durchgeführt haben, sollten sich die Slaves mit dem
Master verbinden können und alle Aktualisierungen mitbekommen, die nach der
Aufnahme des Schnappschusses passieren.


Wenn Sie vergessen haben, die @code{server-id} für den Slave zu setzen,
erhalten Sie folgenden Fehler in der Fehler-Log-Datei:

@example
Warning: one should set server_id to a non-0 value if master_host ist set.
The server will not act as a slave.
@end example

Wenn Sie vergessen haben, selbiges für den Master zu machen, sind die
Slaves nicht in der Lage, sich mit dem Master zu verbinden.

Wenn ein Slave aus irgend welchen Gründen nicht in der Lage ist zu
replizieren, finden Sie Fehlermeldungen in der Fehler-Log-Datei auf dem
Slave.

Sobald ein Slave repliziert, finden Sie eine Datei namens
@code{master.info} im selben Verzeichnis, wo auch Ihre Fehler-Log-Datei
liegt. Die @code{master.info}-Datei wird vom Slave benutzt, um auf dem
Laufenden zu bleiben, wie viel der Binär-Log-Datei des Masters er bereits
abgearbeitet hat. Sie sollten die Datei @strong{NICHT} entfernen oder
editieren, es sei denn, Sie wissen genau, was Sie tun. Selbst in diesem
Fall sollten Sie vorzugsweise den @code{CHANGE MASTER TO}-Befehl benutzen.




@node Replication Features, Replication Options, Replication HOWTO, Replication
@c German node Replikationsfeatures
@subsection Replikationsfeatures und bekannte Probleme

@cindex Optionen, Replikation
@cindex @code{my.cnf}-Datei
@cindex Dateien,@code{my.cnf}

Unten steht eine Erläuterung dessen, was unterstützt wird und was nicht:

@itemize @bullet
@item
Replikation läuft korrekt mit @code{AUTO_INCREMENT}-,
@code{LAST_INSERT_ID}- und @code{TIMESTAMP}-Werten.
@item
@code{RAND()} bei Updates repliziert nicht korrekt. Benutzen Sie
@code{RAND(ein_nicht_zufalls_ausdruck)}, wenn Sie Updates mit
@code{RAND()} replizieren. Sie können zum Beispiel @code{UNIX_TIMESTAMP()}
als Argument für @code{RAND()} benutzen.
@item
Sie müssen auf Master und Slave denselben Zeichensatz
(@code{--default-character-set}) benutzen. Wenn nicht, erhalten Sie
eventuell Fehler wegen doppelter Schlüsseleinträge (duplicate key) auf dem
Slave, weil ein Schlüssel, der auf dem Master als eindeutig betrachtet
wird, das in einem anderen Zeichensatz eventuell nicht ist.
@item
@code{LOAD DATA INFILE} wird korrekt gehandhabt, solange die Datei zur Zeit
der Update-Ausführung noch auf dem Master-Server liegt. @code{LOAD LOCAL
DATA INFILE} wird übersprungen.
@item
Aktualisierungsanfragen, die Benutzer-Variablen benutzen, sind (noch) nicht
replikationssicher.
@item
@code{FLUSH}-Befehle werden nicht in der Binär-Log-Datei gespeichert und
werden deswegen nicht auf den Slaves repliziert. Das stellt normalerweise
kein Problem dar, weil @code{FLUSH} nichts ändert. In Bezug auf die
@code{MySQL}-Berechtigungstabellen heißt das jedoch, dass Sie bei direkten
Änderungen in diesen Tabellen ohne Benutzung des @code{GRANT}-Statements
und der anschließenden Replikation der
@code{MySQL}-Berechtigungs-Datenbank auf den Slaves @code{FLUSH PRIVILEGES}
ausführen müssen, damit die neuen Berechtigungen wirksam werden.
@item
Temporäre Tabellen werden ab Version 3.23.29 korrekt repliziert,
ausgenommen im Fall, dass Sie den Slave-Server schließen (nicht nur den
Slave-Thread), Sie noch einige temporäre Tabellen offen haben und diese bei
nachfolgenden Aktualisierungen benutzt werden. Um mit diesem Problem fertig
zu werden, schließen Sie den Slave mit @code{SLAVE STOP} und prüfen dann
die @code{Slave_open_temp_tables}-Variable, um zu sehen, ob Sie 0 ist. Dann
führen Sie @code{mysqladmin shutdown} aus. Wenn die Variable nicht 0 ist,
starten Sie den Slave-Thread neu mit @code{SLAVE START} und probieren es
noch einmal. Zukünftig (ab Version 4.0) wird es eine sauberere Lösung
geben.
In früheren Versionen wurden temporäre Tabellen nicht korrekt repliziert.
Wir empfehlen, dass Sie entweder auf eine neuere Version aktualisieren oder
vor allen Anfragen mit temporären Tabellen @code{SET SQL_LOG_BIN=0} auf
alle Clients ausführen.
@item
MySQL unterstütz nur einen Master und viele Slaves. In Version 4.x wird ein
Abstimmungsalgorithmus eingebaut, der automatisch den Master umschaltet,
wenn etwas mit dem aktuellen Master schief geht. Ausserdem werden wir
'Agenten'-Prozesse einführen, die bei der Lastverteilung helfen, indem sie
SELECT-Anfragen an verschiedene Slaves senden.
@item
Ab Version 3.23.26 ist es sicher, Server in einer zirkulären
Master-Slave-Beziehung mit angeschaltetem @code{log-slave-updates} zu
verbinden. Beachten Sie jedoch, dass bei dieser Art von Einrichtung viele
Anfrage nicht richtig funktionieren, es sei denn, Ihr Client-Code ist so
geschrieben, dass er sich um mögliche Probleme kümmert, die durch
Aktualisierungen auftreten können, die in unterschiedlicher Reihenfolge auf
verschiedenen Servern laufen.

Das bedeutet, dass Sie eine Einrichtung wie die folgende machen können:

@example
A -> B -> C -> A
@end example

Diese Einrichtung funktioniert nur dann, wenn Sie ausschließlich
Aktualisierungen ausführen, die nicht zwischen den Tabellen zu Konflikten
führen. Mit anderen Worten, wenn Sie Daten in A und C einfügen, sollten Sie
nie eine Zeile in A einfügen, die zu einem Konflikt mit einem Schlüsselwert
bei einem Zeilen-Einfügevorgang in C führt. Ebenfalls sollte Sie nie
dieselben Zeilen auf zwei Servern einfügen, wenn die Reihenfolge, in der
die Aktualisierungen durchgeführt werden, eine Rolle spielt.

Beachten Sie, dass sich das Log-Format in Version 3.23.26 geändert hat, so
das Slaves vor Version 3.23.26 diese nicht lesen können.
@item
Wenn die Anfrage auf dem Slave zu einem Fehler führt, beendet sich der
Slave-Thread und in der @code{.err}-Datei erscheint eine Meldung. Sie
sollten sich dann manuell mit dem Slave verbinden, die Ursache des Fehlers
beheben (zum Beispiel nicht existierende Tabellen) und dann den SQL-Befehl
@code{SLAVE START} laufen lassen (verfügbar ab Version 3.23.16). In Version
3.23.15 müssen Sie den Server neu starten.
@item
Wenn die Verbindung zum Master verloren geht, versucht der Slave
unmittelbar, sich neu zu verbinden, und wenn das fehlschlägt, alle
@code{master-connect-retry} Sekunden (Vorgabe 60 Sekunden). Deswegen ist es
sicher, den Master herunter zu fahren und dann nach einer Weile wieder
hochzufahren. Der Slave ist auch in der Lage, mit
Netzwerk-Verbindungsausfällen umzugehen.
@item
Den Slave (sauber) herunterzufahren ist ebenfalls sicher, weil er sich
merkt, wo er aufgehört hat. Unsauberes Herunterfahren kann zu Problemen
führen, insbesondere dann, wenn der Platten-Cache nicht synchronisiert
wurde, als das System starb. Die Fehlertoleranz Ihres Systems wird stark
verbessert, wenn Sie ein gutes UPS haben.
@item
Wenn der Master auf einem Port auf Anfragen wartet, der nicht Standard ist,
müssen Sie diesen mit dem @code{master-port}-Parameter in @code{my.cnf}
angeben.
@item
In Version 3.23.15 werden alle Tabellen und Datenbanken repliziert. Ab
Version 3.23.16 können Sie die Replikation mit der
@code{replicate-do-db}-Anweisung in @code{my.cnf} auf einen Satz von
Datenbanken beschränken oder einen Satz von Datenbanken mit
@code{replicate-ignore-db} ausschließen. Beachten Sie, dass es bis Version
3.23.23 einen Bug gab, so dass mit @code{LOAD DATA INFILE} nicht sauber
umgegangen wurde, wenn Sie diesen Befehl in einer Datenbank ausführten, die
von der Replikation ausgeschlossen war.
@item
Ab Version 3.23.16 schaltet @code{SET SQL_LOG_BIN = 0}
Replikations-(Binär)-Loggen auf dem Master aus und @code{SET SQL_LOG_BIN =
1} schaltet es wieder an. Sie benötigen die process-Berechtigung, um das
auszuführen.
@item
Ab Version 3.23.19, you can clean up stale Replikation leftovers when
something goes wrong und you want a clean start mit @code{FLUSH MASTER}
und @code{FLUSH SLAVE}-Befehle. In Version 3.23.26 we have renamed them to
@code{RESET MASTER} und @code{RESET SLAVE} respectively to clarify
what they do. The old @code{FLUSH} variants still work, though, for
Kompatibilität.

@item
Ab Version 3.23.21, you can use @code{LOAD TABLE FROM MASTER} for
network backup und to set up Replikation initially. We have recently
received a Anzahl von bug reports concerning it that we are investigating, so
we recommend that you use it only in testing until we make it mehr stable.
@item
Ab Version 3.23.23, you can change masters und adjust log position
mit @code{CHANGE MASTER TO}.
@item
Ab Version 3.23.23, you tell the master that updates in certain
Datenbanken should not be logged to the Binär-Log-Datei mit @code{binlog-ignore-db}.
@item
Ab Version 3.23.26 können Sie @code{replicate-rewrite-db} benutzen, um den
Slave anzuweisen, Aktualisierungen einer Datenbank auf dem Master auf eine
mit einem anderen Namen auf dem Slave anzuwenden.
@item
Ab Version 3.23.28 können Sie @code{PURGE MASTER LOGS TO 'log-name'}
benutzen, um alte Log-Dateien loszuwerden, während der Slave läuft.
@end itemize


@node Replication Options, Replication SQL, Replication Features, Replication
@c German node Replikationsoptionen
@subsection Replikationsoptionen in my.cnf

Wenn Sie Replikation benutzen, empfehlen wir, dass Sie MySQL-Version
3.23.30 oder höher benutzen. Ältere Versionen funktionieren, haben aber
einige Bugs und fehlende Features.

Sowohl auf dem Master als auch auf dem Slave müssen Sie die
@code{server-id}-Option benutzen. Diese setzt eine eindeutige
Replikations-ID. Sie sollten einen eindeutigen Wert im Bereich zwischen 1
und 2^32-1 für jeden Master und Slave benutzen. Beispiel: @code{server-id=3}

In folgender Tabelle stehen die Optionen, die Sie für den @strong{MASTER}
benutzen können:

@multitable @columnfractions .3 .7

@item @strong{Option} @tab @strong{Beschreibung}
@item @code{log-bin=dateiname} @tab
Schreibt in die binäre Update-Log-Datei am angegebenen Ort. Beachten Sie,
dass, wenn Sie ihr einen Parameter mit einer Erweiterung angeben (zum
Beispiel @code{log-bin=/mysql/logs/replikation.log}), Versionen bis zu
3.23.24 während der Replikation nicht richtig funktionieren, wen Sie
@code{FLUSH LOGS} ausführen. Das Problem ist seit Version 3.23.25 behoben.
Wenn Sie Log-Namen dieser Art benutzen, wird @code{FLUSH LOGS} auf dem
binären Log ignoriert. Um das Log zu löschen, führen Sie @code{FLUSH
MASTER} aus. Vergessen Sie dabei nicht, @code{FLUSH SLAVE} auf allen Slaves
laufen zu lassen.Ab Version 3.23.26 sollten Sie @code{RESET MASTER} und
@code{RESET SLAVE} benutzen.

@item @code{log-bin-index=dateiname} @tab
Weil der Benutzer @code{FLUSH LOGS}-Befehle ausführen könnte, muss man
wissen, welches Log momentan aktiv ist und welche in welcher Reihenfolge
durch Log-Rotation herausgenommen wurden. Diese Informationen sind in der
Binär-Log-Index-Datei gespeichert. Der Vorgabewert ist `hostname`.index. 

Beispiel: @code{log-bin-index=datenbank.index}.

@item @code{sql-bin-update-same} @tab
Falls gesetzt, führt das Setzen von @code{SQL_LOG_BIN} auf einen Wert
automatisch dazu, dass @code{SQL_LOG_UPDATE} auf denselben Wert gesetzt
wird, und umgekehrt.

@item @code{binlog-do-db=datenbank} @tab
Weist den Master an, Aktualisierung in die Binär-Log-Datei zu loggen, wenn
die aktuelle Datenbank 'datenbank' ist. Alle anderen Datenbanken werden
ignoriert. Beachten Sie bei der Benutzung, dass Sie sicherstellen sollten,
dass Sie Aktualisierungen nur in der aktuellen Datenbank ausführen.

Beispiel: @code{binlog-do-db=eine_datenbank}.

@item @code{binlog-ignore-db=datenbank} @tab
Weist den Master an, das Aktualisierung der aktuellen Datenbank 'datenbank'
nicht in der Binär-Log-Datei gespeichert werden sollen. ignoriert. Beachten
Sie bei der Benutzung, dass Sie sicherstellen sollten, dass Sie
Aktualisierungen nur in der aktuellen Datenbank ausführen.

Beispiel: @code{binlog-ignore-db=eine_datenbank}
@end multitable

Folgende Tabelle enthält die Optionen, die Sie für @strong{SLAVE} benutzen
können:

@multitable @columnfractions .3 .7

@item @strong{Option} @tab @strong{Beschreibung}
@item @code{master-host=host} @tab
Hostname des Masters oder IP-Adresse für Replikation. Falls nicht gesetzt,
startet der Slave-Thread nicht.

Beispiel: @code{master-host=datenbank-master.meinefirma.de}.

@item @code{master-user=benutzername} @tab
Der Benutzer, den der Slave-Thread für Authentifizierung benutzt, wenn er
sich mit dem Master verbindet. Der Benutzer muss die
@code{FILE}-Berechtigung besitzen. Wenn der Master-Benutzer nicht gesetzt
ist, wird Benutzer @code{test} angenommen.

Beispiel: @code{master-user=steve}.

@item @code{master-password=passwort} @tab
Das Passwort, das der Slave-Thread für Authentifizierung benutzt, wenn er
sich mit dem Master verbindet. Wenn nicht gesetzt, wird ein leeres Passwort
angenommen.

Beispiel: @code{master-password=hund}.

@item @code{master-port=portnummer} @tab
Der Port, auf dem der Master auf Verbindungen wartet. Wenn nicht gesetzt,
wird die kompilierte Einstellung von @code{MYSQL_PORT} angenommen. Wenn Sie
nicht an den @code{configure}-Optionen gedreht haben, sollte das 3306 sein.

Beispiel: @code{master-port=3306}.

@item @code{master-connect-retry=sekunden} @tab
Die Anzahl Sekunden, die der Slave-Thread schläft, bevor er wiederum
versucht, sich mit dem Master zu verbinden, falls der Master herunter fuhr
oder die Verbindung verloren ging. Vorgabewert ist 60.

Beispiel: @code{master-connect-retry=60}.

@item @code{master-ssl} @tab
Schaltet SSL an.

Beispiel: @code{master-ssl}.

@item @code{master-ssl-key} @tab
Der Name der SSL-Schlüsseldatei für den Master.

Beispiel: @code{master-ssl-key=SSL/master-key.pem}.

@item @code{master-ssl-cert} @tab
Der Dateiname des SSL-Zertifikats für den Master.

Beispiel: @code{master-ssl-key=SSL/master-cert.pem}.

@item @code{master-info-file=dateiname} @tab
Der Speicherort der Datei, die sich merkt, bis wohin der Master während des
Replikationsprozesses verfolgt wurde. Vorgabewert ist master.info im data-
Verzeichnis.

Beispiel: @code{master-info-file=master.info}.

@item @code{replicate-do-table=datenbank.tabelle} @tab
Weist den Slave-Thread an, die Replikation auf die angegebene Tabelle zu
beschränken. Um mehr als eine Tabelle anzugeben, benutzen Sie die Anweisung
mehrfach, einmal für jede Tabelle. Das funktioniert auch bei
Datenbank-übergreifenden Aktualisierungen, im Gegensatz zu
@code{replicate-do-db}.

Beispiel: @code{replicate-do-table=eine_datenbank.eine_tabelle}.

@item @code{replicate-ignore-table=datenbank.tabelle} @tab
Weist den Slave-Thread an, die angegebene Tabelle nicht zu replizieren. Um
mehr als eine Tabelle anzugeben, die ignoriert werden soll, geben Sie die
Anweisung mehrfach ein, einmal für jede Tabelle. Das funktioniert auch bei
Datenbank-übergreifenden Aktualisierungen, im Gegensatz zu
@code{replicate-ignore-db}.

Beispiel: @code{replicate-ignore-table=eine_datenbank.eine_tabelle}.

@item @code{replicate-wild-do-table=datenbank.tabelle} @tab
Weist den Slave-Thread an, die Replikation auf Tabellen zu beschränken, die
dem angegebenen Platzhalter-Muster entsprechen. Um mehr als ein
Tabellenmuster anzugeben, das ignoriert werden soll, geben Sie die
Anweisung mehrfach ein, einmal für jedes Tabellenmuster. Das funktioniert
auch bei Datenbank-übergreifenden Aktualisierungen.

Beispiel: @code{replicate-wild-do-table=foo%.bar%} repliziert nur
Aktualisierungen auf Tabellen in allen Datenbanken, die mit 'foo' anfangen
und deren Tabellennamen mit 'bar' beginnen.

@item @code{replicate-wild-ignore-table=datenbank.tabelle} @tab
Weist den Slave-Thread an, Tabellen nicht zu replizieren, die dem
angegebenen Platzhalter-Muster entsprechen. Um mehr als ein
Tabellenmuster anzugeben, das ignoriert werden soll, geben Sie die
Anweisung mehrfach ein, einmal für jedes Tabellenmuster. Das funktioniert
auch bei Datenbank-übergreifenden Aktualisierungen.

Beispiel: @code{replicate-wild-ignore-table=foo%.bar%} aktualisiert keine
Tabellen in Datenbanken, die mit 'foo' anfangen und deren Tabellennamen mit
'bar' beginnen.

@item @code{replicate-ignore-db=datenbank} @tab
Weist den Slave-Thread an, die angegebene Datenbank nicht zu replizieren.
Um mehr als eine Datenbank anzugeben, die ignoriert werden soll, geben Sie
die Anweisung mehrfach ein, einmal für jede Datenbank. Diese Option
funktioniert nicht für Datenbank-übergreifende Aktualisierungen. Wenn Sie
Datenbank-übergreifende Aktualisierungen brauchen, stellen Sie sicher, dass
Sie Version 3.23.28 oder höher verwenden und benutzen Sie
@code{replicate-wild-ignore-table=datenbank.%}

Beispiel: @code{replicate-ignore-db=eine_datenbank}.

@item @code{replicate-do-db=datenbank} @tab

Weist den Slave-Thread an, die Replikation auf die angegebene Datenbank zu
beschränken. Um mehr als eine Datenbank anzugeben, benutzen Sie die
Anweisung mehrfach, einmal für jede Datenbank. Beachten Sie, dass das nicht
funktioniert, wenn Sie Datenbank-übergreifende Anfragen wie @code{UPDATE
eine_datenbank.eine_tabelle SET foo='bar'} ausführen, während Sie eine
andere oder keine Datenbank ausgewählt haben. Wenn Sie
Datenbank-übergreifende Aktualisierungen brauchen, stellen Sie sicher, dass
Sie Version 3.23.28 oder höher verwenden und benutzen Sie
@code{replicate-wild-do-table=datenbank.%}.

Beispiel: @code{replicate-do-db=eine_datenbank}.

@item @code{log-slave-updates} @tab
Weist den Slave an, Aktualisierungen vom Slave-Thread in die binäre
Log-Datei zu schreiben. Ist vorgabemäßig ausgeschaltet. Sie müssen diese
Option anschalten, wenn Sie planen, die Slave in eine zirkuläre Kette zu
hängen ('Daisy-Chain').

@item @code{replicate-rewrite-db=von_name->zu_name} @tab
Aktualisierungen auf eine Datenbank mit einem anderen Namen als dem
Orginalnamen.

Beispiel: @code{replicate-rewrite-db=master_datenbank->slave_datenbank}.

@item @code{skip-slave-start} @tab
Weist den Slave-Server an, den Slave nicht beim Hochfahren zu starten. Der
Benutzer kann ihn später mit @code{SLAVE START} starten.

@item @code{slave_read_timeout=#} @tab
Anzahl von Sekunden, die der Slave auf weitere Daten vom Master wartet,
bevor er abbricht.
@end multitable


@node Replication SQL, Replication FAQ, Replication Options, Replication
@c German node SQL und Replikation
@subsection SQL-Befehle in Bezug auf Replikation

@cindex SQL-Befehle, Replikation
@cindex Befehle, Replikation
@cindex Replikation, Befehle

Replikation kann über die SQL-Schnittstelle gesteuert werden. Hier eine
Zusammenfassung der Befehle:

@multitable @columnfractions .30 .70
@item @strong{Befehl} @tab @strong{Beschreibung}

@item @code{SLAVE START}
 @tab Startet den Slave-Thread. (Slave)

@item @code{SLAVE STOP}
 @tab Hält den Slave-Thread an. (Slave)

@item @code{SET SQL_LOG_BIN=0}
 @tab Schaltet das Loggen in die Update-Log-Datei aus, wenn der Benutzer
die process-Berechtigung hat. Wird ansonsten ignoriert. (Master)

@item @code{SET SQL_LOG_BIN=1}
 @tab Schaltet das Loggen in die Update-Log-Datei wieder an, wenn der
Benutzer die process-Berechtigung hat. Wird ansonsten ignoriert. (Master)

@item @code{SET SQL_SLAVE_SKIP_COUNTER=n}
 @tab Die nächsten @code{n} Ereignisse vom Master ignorieren. Gilt nur,
wenn der Slave-Thread nicht läuft, gibt ansonsten einen Fehler aus.
Nützlich für den Ausgleich von Replikationsabweichungen.

@item @code{RESET MASTER}
 @tab Löscht alle Binär-Log-Dateien, die in der Index-Datei aufgeführt
sind, und setzt die BinärLog-Index-Datei auf leer zurück. In Versionen vor
3.23.26 versions heißt dieser Befehl @code{FLUSH MASTER}. (Master)

@item @code{RESET SLAVE}
 @tab Führt dazu, dass der Slave seine Replikationsposition in den
Master-Logs vergisst. In Versionen vor 3.23.26 versions heißt dieser
Befehl @code{FLUSH SLAVE}. (Slave)

@item @code{LOAD TABLE tabelle FROM MASTER}
 @tab Lädt eine Kopie der Tabelle vom Master auf den Slave. (Slave)

@item @code{CHANGE MASTER TO master_def_list}
 @tab Ändert die Master-Parameters auf den Wert, der in
@code{master_def_list} angegeben ist, und startet den Slave-Thread neu.
@code{master_def_list} ist eine durch Kommas getrennte Liste
@code{master_def}, wobei @code{master_def} eins der folgenden Elemente ist:
@code{MASTER_HOST}, @code{MASTER_USER}, @code{MASTER_PASSWORD},
@code{MASTER_PORT}, @code{MASTER_CONNECT_RETRY}, @code{MASTER_LOG_FILE}
oder @code{MASTER_LOG_POS}. Beispiel:

@example

CHANGE MASTER TO
  MASTER_HOST='master2.meinefirma.com',
  MASTER_USER='replikation',
  MASTER_PASSWORD='gro33esgeheimnis',
  MASTER_PORT=3306,
  MASTER_LOG_FILE='master2-bin.001',
  MASTER_LOG_POS=4;

@end example

Sie müssen nur die Werte angeben, die geändert werden sollen. Die Werte,
die Sie auslassen, bleiben dieselben, ausser wenn Sie den Host oder den
Port ändern. In diesem Fall nimmt der Slave an, dass der Master ein anderer
ist, weil Sie sich zu einem anderen Host oder über einen anderen Port
verbinden. Daher treffen die alten Werte von Log und Position nicht mehr zu
und werden automatisch auf eine leere Zeichenkette bzw. auf 0 zurück
gesetzt (dem Startwert). Beachten Sie, dass sich der Slave beim Neustart an
seinen alten Master erinnert. Falls das nicht wünschenswert ist, sollten
Sie die @file{master.info}-Datei löschen, bevor Sie neu starten. Der Slave
liest dann seinen Master aus der Datei @code{my.cnf} oder von der
Kommandozeile. (Slave)

@item @code{SHOW MASTER STATUS} 
 @tab Stellt Statusinformationen über die Binär-Log-Datei des Masters zur
Verfügung. (Master)

@item @code{SHOW SLAVE STATUS} 
 @tab Stellt Statusinformationen über die wichtigsten Parameter des
Slave-Threads zur Verfügung. (Slave)
@item @code{SHOW MASTER LOGS} 
 @tab Nur verfügbar ab Version 3.23.28. Listet die Binär-Log-Dateien auf
dem Master auf. Sie sollten diesen Befehl vor @code{PURGE MASTER LOGS TO}
benutzen, um herauszufinden, wie weit Sie gehen sollten.

@item @code{PURGE MASTER LOGS TO 'logname'}
 @tab Verfügbar ab Version 3.23.28. Löscht alle Replikations-Logs, die in
der Index-Log-Datei aufgeführt sind, die vor dem angegebenen Log liegen und
entfernt Sie aus dem Log-Index, so dass die angegebene Log-Datei nunmehr
die erste wird. Beispiel:

@example
PURGE MASTER LOGS TO 'mysql-bin.010'
@end example

Dieser Befehl macht nichts und schlägt mit einer Fehlermeldung fehl, wenn
Sie einen aktiven Slave haben, der momentan eine der Log-Dateien liest, die
Sie zu löschen versuchen. Wenn Sie jedoch einen schlafenden Slave haben und
gerade eine der Log-Dateien löschen, die dieser Slave lesen will, wird der
Slave nicht in der Lage sein zu replizieren, sobald er wach wird. Der
Befehl kann sicher verwendet werden, während Slaves replizieren - Sie
brauchen diese also nicht anhalten.

Zuerst müssen Sie alle Slaves mit @code{SHOW SLAVE STATUS} überprüfen, um
festzustellen, an welcher Log-Datei sie gerade sind, dann eine Auflistung
aller Log-Dateien auf dem Master mit @code{SHOW MASTER LOGS} machen, die
früheste davon herausfinden, an der noch ein Slave arbeitet (wenn alle
Slaves aktuell sind, ist das die letzte Log-Datei auf der Liste), dann alle
Logs, die Sie löschen wollen, sichern (optional), und schließlich bis zum
Ziel-Log löschen.

@end multitable


@node Replication FAQ, Replication Problems, Replication SQL, Replication
@c German node Replikations-FAQ
@subsection Replikation - Häufig gestellte Fragen

@cindex @code{Binlog_Dump}
@strong{Frage}: Warum sehe ich manchmal mehr als eine
@code{Binlog_Dump}-Thread auf dem Master, nachdem ich den Slave neu
gestartet habe?

@strong{Antwort}: @code{Binlog_Dump} ist ein kontinuierlicher Prozess, der
folgendermaßen vom Server gehandhabt wird:

@itemize @bullet
@item
Zu den Aktualisierungen aufschließen.
@item
Sobald keine Aktualisierungen mehr übrig sind, in den Zustand
@code{pThread_cond_wait()} gehen, durch den er entweder durch eine
Aktualisierung oder einen Kill erweckt werden kann.
@item
Beim Aufwachen den Grund dafür prüfen. Wenn er nicht sterben soll,
mit der @code{Binlog_dump}-Schleife weitermachen.
@item
Wenn ein schwerer Fehler auftritt, wenn zum Beispiel ein toter Client
entdeckt wird, die Schleife beenden.
@end itemize

Wenn der Slave-Thread also beim Slave anhält, bemerkt das der entsprechende
@code{Binlog_Dump}-Thread auf dem Master solange nicht, bis zumindest eine
Aktualisierung (oder ein Kill) auf den Master durchgeführt wird, was
benötigt wird, um ihn von @code{pThread_cond_wait()} aufzuwecken. In der
Zwischenzeit könnte der Slave bereits eine weitere Verbindung geöffnet
haben, die in einem weiteren @code{Binlog_Dump}-Thread resultiert.

Das beschriebene Problem sollten in Versionen ab 3.23.26 nicht auftreten.
In Version 3.23.26 kam @code{server-id} für jeden Replikationsserver hinzu,
und nun werden alle alten Zombie-Threads auf dem Master gekillt, wenn ein
neuer Replikations-Thread sich vom selben Slave aus verbindet.

@strong{Frage}: Wie rotiere ich Replikations-Logs?

@strong{Antwort}: In Version 3.23.28 sollten Sie den @code{PURGE MASTER
LOGS TO}-Befehl benutzen, nachdem festgestellt wurde, welche Logs gelöscht
werden können und nachdem sie optional gesichert wurden. In früheren
Versionen ist der Prozess sehr viel anstrengender und kann nicht sicher
durchgeführt werden, ohne alle Slaves anzuhalten, falls Sie planen,
Log-Namen wiederholt zu verwenden. Sie müssen die Slave-Threads anhalten,
die Binär-Log-Index-Datei editieren, alle alten Logs löschen, den Master
neu starten, die Slave-Threads neu starten und dann die alten Log-Dateien
entfernen.


@strong{Frage}: Wie aktualisiere ich bei einer laufenden
Replikationseinrichtung?

@strong{Antwort}: Wenn Sie vor Version 3.23.26 aktualisieren, sollten Sie
nur die Master-Tabellen sperren, warten, bis die Slaves auf aktuellem Stand
sind, und dann @code{FLUSH MASTER} auf dem Master und @code{FLUSH SLAVE}
auf dem Slave laufen lassen, um die Logs zurückzusetzen, und danach neue
Versionen des Masters und des Slaves neu starten. Beachten Sie, dass der
Slave für einige Zeit heruntergefahren bleiben kann - weil der Master alle
Aktualisierung loggt, wird der Slave in der Lage sein, auf den aktuellen
Stand zu kommen, sobald er hoch gefahren ist und sich verbinden kann.

Nach Version 3.23.26 wurde das Replikationsprotokoll für Änderungen
gesperrt, daher können Sie Masters und Slaves im laufenden Betrieb auf eine
neuere 3.23-Version aktualisieren, und Sie können unterschiedliche
Versionen von MySQL auf Slave und Master laufen haben, solange beide neuer
als Version 3.23.26 sind.

@cindex Replikation, Zweiweg-
@strong{Frage}: Welche Dinge sollte ich beachten, wenn ich
Zweiweg-Replikation aufsetze?

@strong{Antwort}: MySQL-Replikation unterstützt derzeit kein
Sperr-Protokoll zwischen Master und Slave, um die Atomizität einer
verteilten (Cross-Server-) Aktualisierung zu gewährleisten. Mit anderen
Worten ist es für einen Client A möglich, eine Aktualisierung zu Co-Master
1 zu machen. In der Zwischenzeit, bevor er sich an Co-Master 2 wendet,
könnte Client B eine Aktualisierung auf Co-Master 2 machen, die dazu führt,
dass die Aktualisierung von Client A anders funktioniert als auf Master 1.
Wenn daher die Aktualisierung von Client A zu Co-Master 2 durchdringt,
produziert das Tabellen, die anders sein werden als die auf Co-Master 1,
selbst nachdem alle Aktualisierungen von Co-Master 2 ebenfalls durchgeführt
wurden. Daher sollten sie keine zwei Server in einer Zweiweg-Replikation
verketten, es sei denn, Sie können sicher sein, dass Ihre Aktualisierungen
immer in bestimmter Reihenfolge ablaufen, oder indem Sie irgendwie in Ihrem
Client-Code Vorkehrungen gegen Aktualisierung treffen, die nicht in der
richtigen Reihenfolge sind.

Sie müssen sich auch darüber im Klaren sein, dass Zweiweg-Replikation Ihre
Performance nicht wesentlich verbessert, falls überhaupt, sofern
Aktualisierungen betroffen sind. Beide Server müssen ungefähr dieselbe
Menge Aktualisierungen durchführen, was auch ein Server hätte tun können.
Der einzige Unterschied liegt darin, dass es sehr viel weniger
Lock-Contention gibt, weil die Aktualisierungen, die von einem anderen
Server stammen, in einem Slave-Thread serialisiert werden. Dennoch kann der
erzielte Vorteil durch Netzwerk-Verzögerungen konterkariert werden.

@cindex Performance, verbessern
@cindex erhöhen, Performance
@strong{Frage}: Wie kann ich Replikation benutzen, um die Performance
meines Systems zu verbessern?

@strong{Antwort}: Sie sollten einen Server als Master aufsetzen und alle
Schreibvorgänge zu ihm lenken, und so viele Slaves wie möglich einrichten
und die Lesevorgänge zwischen Master und Slaves verteilen. Ausserdem können
Sie die Slaves mit @code{--skip-bdb}, @code{--low-priority-updates} und
@code{--delay-key-write-for-all-tables} starten, um für die Slaves
Geschwindigkeitsverbesserungen zu erzielen. In diesem Fall benutzt der
Slave nicht transaktionale @code{MyISAM}-Tabellen anstelle von
@code{BDB}-Tabellen, um mehr Geschwindigkeit zu erhalten.

@strong{Frage}: Was muss ich in meinem Client-Code tun, damit dieser
Performance-verbessernde Replikation nutzt?

@strong{Antwort}:
Wenn der Teil Ihres Codes, der für den Datenbankzugriff zuständig ist,
korrekt abstrahiert / modularisiert ist, sollte die Konvertierung zur
replizierten Einrichtung sehr glatt und einfach verlaufen: Ändern Sie die
Implementation Ihres Datenbankzugriffs so, dass von irgend einem Slave oder
dem Master gelesen und immer zum Master geschrieben wird. Wenn Ihr Code
nicht diese Abstraktionsebene besitzt, ist die Einrichtung eines
Replikationssystems ein guter Grund, ihn zu säubern. Sie könnten damit
beginnen, eine Wrapper-Bibliothek oder ein Wrapper-Modul mit folgenden
Funktionen zu benutzen:

@itemize @bullet
@item
@code{safe_writer_connect()}
@item
@code{safe_reader_connect()}
@item
@code{safe_reader_query()}
@item
@code{safe_writer_query()}
@end itemize

@code{safe_} bedeutet, dass die Funktion sich um die Handhabung jeglicher
Fehlerbedingungen kümmert.

Danach sollten Sie Ihren Client-Code so umwandeln, dass er die
Wrapper-Bibliothek benutzt. Dieser Prozess kann anfangs etwas anstrengend
und aufregend sein, wird sich aber auf lange Sicht lohnen. Alle
Applikationen, die dem geschilderten Muster folgen, werden ebenfalls Nutzen
aus der Master-/Slaves-Lösung ziehen. Der Code wird sich viel einfacher
pflegen lassen und Optionen zur Problemlösung werden trivial sein. Sie
brauchen einfach nur ein oder zwei Funktionen zu ändern, um zum Beispiel zu
loggen, wie lang jede Anfrage dauerte, oder welche Anfrage unter Ihren
Tausenden einen Fehler produzierte. Wenn Sie schon eine Menge Code
geschrieben haben, wollen Sie den Umwandlungsprozess wahrscheinlich
automatisieren. Hierfür können Sie zum Beispiel Monty's
@code{replace}-Dienstprogramm benutzen, das der Standard-Distribution von
MySQL beiliegt, oder Ihr eigenes Perl-Skript schreiben. Hoffentlich folgt
Ihr Code irgend einem erkennbaren Muster - wenn nicht, ist es
wahrscheinlich ohnehin besser, ihn neu zu schreiben, oder zumindest, ihn
durchzugehen und manuell in ein Muster zu bringen.

Beachten Sie, dass Sie natürlich andere Namen für die Funktionen verwenden
können. Wichtig ist, eine einheitliche Schnittstelle für Verbindungen zum
Lesen, Verbindungen zum Schreiben, Durchführen von Lesevorgängen und
Durchführung von Schreibvorgängen zu haben.


@strong{Frage}: Wann und in welchem Umfang kann MySQL-Replikation die
Performance meines Systems verbessern?

@strong{Antwort}: MySQL-Replikation bringt die meisten Vorteile auf einem
System mit häufigen Lesevorgängen und nicht so häufigen Schreibvorgängen.
Theoretisch können Sie eine Einrichtung aus einem Master und vielen Slaves
so skalieren, dass Sie solange Slaves hinzufügen, bis Sie entweder keine
Netzwerk-Bandbreite mehr haben oder bis Ihre Aktualisierungslast so weit
ansteigt, dass der Master sie nicht mehr handhaben kann.

Im festlegen zu können, wie viele Slaves sie haben können, bevor die
zusätzlichen Vorteile aufgewogen werden, und um wieviel Sie die Performance
Ihrer Site steigern können, müssen Sie Ihre Anfragenmuster kennen und
empirisch (durch Benchmarks) festlegen, wie das Verhältnis zwischen dem
Durchsatz von Lesevorgängen (pro Sekunde, oder @code{max_reads}) und
Schreibvorgängen (@code{max_writes}) auf einem typischen Master und einem
typischen Slave ist. Das unten stehende Beispiel zeigt Ihnen eine eher
vereinfachte Berechnung, was Sie mit Replikation für ein imaginäres System
erreichen können.

Nehmen wir an, Ihr Systemlast besteht aus 10% Schreibvorgängen und 90%
Lesevorgängen, und Sie haben festgestellt, dass @code{max_reads} = 1200 - 2
* @code{max_writes} ist. Mit anderen Worten kann Ihr System 1.200
Lesevorgänge pro Sekunde ohne Schreibzugriffe ausführen, und der
durchschnittliche Schreibvorgang ist zweimal so langsam wie der
durchschnittliche Lesevorgang, und das Verhältnis ist linear. Nehmen wir
ferner an, dass Ihr Master und Slave dieselbe Kapazität haben, und dass es
N Slaves und 1 Master gibt. Dann gilt für jeden Server (Master oder Slave):

@code{lesen = 1200 - 2 * schreiben} (aus Benchmarks)

@code{lesen = 9 * schreiben / (N + 1) } (lesen aufgeteilt, aber schreiben
geht an alle Server)

@code{9 * schreiben / (N+1) + 2 * schreiben = 1200}

@code{schreiben = 1200/(2 + 9/(N+1)}

Wenn also N = 0, was bedeutet, dass es keine Replikation gibt, kann Ihr
System 1200 / 11, also etwa 109 Schreibvorgänge pro Sekunden handhaben (was
heißt, dass Sie neunmal so viele Lesevorgänge haben, was der Natur Ihrer
Applikation entspricht).

Wenn N = 1 ist, können Sie bis zu 184 Schreibvorgänge pro Sekunde haben.

Wenn N = 8 ist, können Sie bis zu 400 haben.

Wenn N = 17 ist, können Sie 480 haben.

Wenn schließlich N gegen unendlich geht (und Ihr Budget gegen negativ
unendlich), können Sie sehr nahe an 600 Schreibvorgänge pro Sekunde kommen
und damit den Systemdurchsatz um etwa den Faktor 5,5 erhöhen. Mit nur 8
Servern jedoch kommen Sie bereits auf eine Steigerung um fast den Faktor 4.

Beachten Sie, dass diese Berechnungen von unbegrenzter Netzwerk-Bandbreite
ausgehen und verschiedene andere Faktoren vernachlässigen, die auf Ihrem
System signifikant sein könnten. In vielen Fällen werden Sie nicht in der
Lage sein, präzise vorauszusagen, was auf Ihrem System passieren wird, wenn
Sie N Replikations-Slaves hinzufügen. Dennoch kann die Beantwortung
folgender Fragen Ihnen helfen zu entscheiden, ob und wie viel (wenn
überhaupt) Replikation bewirken kann, dass sich Ihre System-Performance
verbessert:

@itemize @bullet
@item
Was ist das Lese-/Schreibverhältnis auf Ihrem System?
@item
Wieviel zusätzliche Schreiblast kann ein Server handhaben, wenn Sie die
Leselast verringern?
@item
Für wie viele Slave haben Sie Bandbreite auf Ihrem Netzwerk?
@end itemize

@strong{Frage}: Wie kann ich Replikation benutzen, um Redundanz / hohe
Verfügbarkeit zur Verfügung zu stellen?

@strong{Antwort}: Mit den momentan verfügbaren Features würden Sie einen
Master und einen Slave (nicht mehrere Slaves) aufsetzen und ein Skript
schreiben, das den Master beobachtet, um zu sehen, ob er hochgefahren ist,
und Ihre Applikationen und die Slaves anweisen, den Master im Falle von
Fehlschlägen zu ändern. Einige Vorschläge:
set up a master und a slave (or several slaves) und write a Skript

@itemize @bullet
@item
Um einem Slave mitzuteilen, den Master zu ändern, benutzen Sie den
@code{CHANGE MASTER TO}-Befehl.
@item
Eine gute Möglichkeit, Ihre Applikationen darüber informiert zu halten, wo
der Master ist, ist ein dynamischer DNS-Eintrag für den Master. Bei
@strong{bind} können Sie @code{nsupdate} benutzen, um Ihr DNS dynamisch zu
aktualisieren.
@item
Sie sollten Ihre Slaves mit der @code{log-bin}-Option und ohne
@code{log-slave-updates} laufen lassen. Auf diese Art wird der Slave bereit
sein, ein Master zu werden, sobald Sie @code{STOP SLAVE} eingeben,
@code{RESET MASTER} und @code{CHANGE MASTER TO} auf den anderen Slaves. Das
wird auch dabei helfen, fehlgelaufene Aktualisierungen zu entdecken, die
auf Grund von Fehlkonfiguration des Slaves passieren (im Idealfall sollten
Sie die Zugriffsrechte so konfigurieren, dass kein Client einen Slave
aktualisieren kann, ausser der Slave-Thread), in Kombination mit den Bugs
in Ihren Client-Programmen (die den Slave nie direkt aktualisieren
sollten).

@end itemize

Momentan arbeiten wir an der Integration eines Systems in MySQL, das
automatisch den Master auswählt, aber bis es fertig ist, müssen Sie Ihre
eigenen Beobachtungswerkzeuge schaffen.


@node Replication Problems,  , Replication FAQ, Replication
@c German node Replikationsprobleme
@subsection Problemlösung bei Replikation

Wenn Sie den Anweisungen gefolgt sind und Ihre Replikationseinrichtung
nicht funktioniert, beseitigen Sie zunächst die Möglichkeit von
Benutzerfehlern, indem Sie folgendes prüfen:

@itemize @bullet
@item
Loggt der Master in die Binär-Log-Datei? Prüfen Sie das mit @code{SHOW
MASTER STATUS}. Wenn das der Fall ist, ist die @code{Position} nicht 0.
Wenn nicht, überprüfen Sie, ob Sie dem Master die @code{log-bin}-Option
angegeben und die @code{server-id} gesetzt haben.
@item
Läuft der Slave? Überprüfen Sie das mit @code{SHOW SLAVE STATUS}. Die
Antwort steht in der @code{Slave_running}-Spalte. Wenn nicht, überprüfen
Sie die Slave-Optionen und überprüfen Sie die Fehler-Log-Datei auf
Meldungen.
@item
Wenn der Slave läuft, hat er eine Verbindung mit dem Master hergestellt?
Führen Sie @code{SHOW PROCESSLIST} aus, finden Sie den Thread mit dem
@code{System user}-Wert in der @code{User}-Spalte und @code{none} in der
@code{Host}-Spalte und überprüfen Sie die @code{State}-Spalte. Wenn dort
steht @code{connecting to master}, überprüfen Sie die Berechtigungen für
den Replikations-Benutzer auf dem Master, den Master-Hostnamen, Ihre
DNS-Einrichtung, ob der Master tatsächlich läuft, ob er durch den Slave
erreichbar ist, und wenn all das in Ordnung zu sein scheint, lesen Sie die
Fehler-Log-Dateien.
@item
Wenn der Slave lief, aber dann anhielt, schauen Sie in die Ausgabe von SHOW
SLAVE STATUS und überprüfen Sie die Fehler-Log-Dateien. Das passiert
üblicherweise, wenn eine Anfrage, die auf dem Master funktionierte, auf dem
Slave fehlschlägt. Das sollte nie vorkommen, wenn Sie einen korrekten
Schnappschuss des Masters aufgenommen haben und die Daten nie auf dem Slave
ausserhalb des Slave-Threads verändern. Wenn das doch auftritt, ist es ein
Bug und sollte berichtet werden.
@item
Wenn eine Anfrage, die auf dem Master funktionierte, nicht auf dem Slave
läuft, und eine komplette Datenbank-Synchronisation (das richtige, was man
tun sollte) nicht ratsam erscheint, versuchen Sie folgendes:
@itemize @minus
@item
Überprüfen Sie zunächst, ob irgend ein 'streunender' Datensatz im Weg ist.
Finden Sie heraus, wie das geschehen konnte, dann löschen Sie ihn und
lassen @code{SLAVE START} laufen.
@item
Wenn das Obige nicht funktioniert oder nicht zutrifft, versuchen Sie
herauszufinden, ob es sicher ist, die Aktualisierung manuell durchzuführen
(falls notwendig) und ignorieren Sie dann die nächste Anfrage vom Master.
@item
Wenn Sie sich entschieden haben, dass Sie die nächste Anfrage überspringen
können, führen Sie @code{SET SQL_SLAVE_SKIP_COUNTER=1; SLAVE START;} aus,
um eine Anfrage zu überspringen, die kein auto_increment oder
last_insert_id benutzt, ansonsten @code{SET SQL_SLAVE_SKIP_COUNTER=2; SLAVE
START;}. Der Grund, warum auto_increment- / last_insert_id-Anfragen anders
sind, liegt darin, dass für Sie zwei Ereignisse in der Binär-Log-Datei des
Masters verzeichnet sind.

@item
Wenn Sie sicher sind, dass der Slave perfekt mit dem Master synchronisiert
gestartet ist, und dass niemand die fraglichen Tabellen ausserhalb des
Slave-Threads aktualisiert hat, berichten Sie den Bug, damit wir die oben
beschriebenen Tricks nicht noch einmal machen müssen.
@end itemize
@item
Stellen Sie sicher, dass es sich nicht um alten Bug handelt, indem
Sie auf die aktuellste Version aktualisieren.
@item
Wenn alles Weitere fehlschlägt, lesen Sie die Fehler-Log-Dateien. Wenn
diese Groß sind, führen Sie ein @code{grep -i slave /pfad/zu/your-log.err}
auf dem Slave durch. Es gibt kein allgemeines Muster, nach dem man auf dem
Master suchen könnte, weil die einzigen Fehler, die dieser mitschreibt,
allgemeine Systemfehler sind - falls möglich, wird er Fehler an die Slaves
senden, wenn etwas schief ging.
@end itemize

Wenn Sie sicher sind, dass es keine Benutzerfehler gibt und die Replikation
immer noch nicht funktioniert oder nicht stabil ist, ist es an der Zeit,
einen Bug-Bericht auszuarbeiten. Um dem Bug auf die Spur zu kommen,
brauchen wir soviel Informationen von Ihnen wie möglich. Bitte nehmen Sie
sich etwas Zeit und schreiben Sie einen guten Bug-Bericht. Im Idealfall
hätten wir gerne einen Test-Fall in dem Format, das Sie im
@code{mysql-test/t/rpl*}-Verzeichnis des Source-Baums finden. Wenn Sie
einen solchen Test-Fall schicken, können Sie in den meisten Fällen ein Patch
innerhalb von ein oder zwei Tagen erwarten. Diese Zeitspanne hängt
allerdings von einer Anzahl weiterer Faktoren ab.

Die zweitbeste Option ist ein einfaches Programm mit leicht
konfigurierbaren Verbindungsargumenten für Master und Slave, das das
Problem auf Ihrem System veranschaulicht. Sie können dies in Perl oder C
schreiben, abhängig davon, welche Sprache Sie besser beherrschen.

Wenn Sie den Bug auf eine der beiden oben beschriebenen Weisen
demonstrieren können, benutzen Sie @code{mysqlbug}, um einen Bug-Bericht
vorzubereiten, und schicken Sie ihn an @email{bugs@@lists.mysql.com}. Wenn
Sie ein 'Phantom' haben - ein Problem, das auftritt, aber nicht einfach
reproduziert werden kann - tun Sie folgendes:

@itemize @bullet
@item
Stellen Sie sicher, dass kein Benutzerfehler im Spiel ist. Beispielsweise
könnte der Slave ausserhalb des Slave-Threads aktualisiert werden - dann
sind die Daten nicht synchronisiert und Sie haben womöglich einen Fehler
wegen doppelter Schlüsseleinträge bei Aktualisierungen, wobei der
Slave-Thread dann anhält und darauf wartet, dass Sie die Tabellen manuell
in Ordnung und in Synchronisation bringen.
@item
Lassen Sie den Slave mit @code{log-slave-updates} und @code{log-bin} laufen
- das behält eine Log-Datei aller Aktualisierungen auf dem Slave bei.
@item
Sichern Sie alle Beweise, bevor Sie die Replikation zurück setzen. Wenn wir
keine oder nur schemenhafte Informationen haben, brauchen wir eine Weile,
um dem Problem auf den Grund zu gehen. Die Beweise, die Sie für uns sammeln
sollten, sind:
@itemize @minus
@item
Alle Binär-Log-Dateien auf dem Master.
@item
Alle Binär-Log-Dateien auf dem Slave.
@item
Die Ausgabe von @code{SHOW MASTER STATUS} auf dem Master zu der Zeit, als
Sie das Problem entdeckten.
@item
Die Ausgabe von @code{SHOW SLAVE STATUS} auf dem Master zu der Zeit, als
Sie das Problem entdeckten.
@item
Fehler-Log-Dateien auf Master und Slave.
@end itemize
@item
Benutzen Sie @code{mysqlbinlog}, um die Binär-Log-Dateien zu untersuchen.
Folgendes sollte hilfreich sein, um eine Anfrage zu finden, die Probleme
verursacht, zum Beispiel:
@example
mysqlbinlog -j pos_from_slave_status /pfad/zu/log_from_slave_status | head
@end example
@end itemize

Sobald Sie die Beweise des Phantomproblems gesammelt haben, versuchen Sie
zuerst, es in einen separaten Test-Fall zu isolieren. Berichten Sie dann
das Problem an @email{bugs@@lists.mysql.com}, wobei Sie soviel
Informationen wie möglich mitschicken.




@node MySQL Optimisation, Reference, MySQL Database Administration, Top
@c German node MySQL-Optimierung
@chapter MySQL-Optimierung



Optimierung ist eine komplizierte Aufgabe, weil sie ein umfassendes
Verständnis des gesamten Systems voraussetzt. Es ist möglich, einige lokale
Optimierungen Ihres Systems oder Ihrer Applikation mit geringem Wissen
durchzuführen. Je optimaler Sie allerdings Ihr System gestalten wollen,
desto mehr müssen Sie darüber wissen.

Dieses Kapitel erklärt und gibt Beispiele für verschiedene Möglichkeiten,
MySQL zu optimieren. Denken Sie allerdings daran, dass es immer noch
zusätzliche Möglichkeiten gibt, das System noch schneller zu machen.


@menu
* Optimise Overview::           
* Query Speed::                 
* Locking Issues::              
* Optimising Database Structure::  
* Optimising the Server::       
* Disk issues::                 
@end menu

@node Optimise Overview, Query Speed, MySQL Optimisation, MySQL Optimisation
@c German node Überblick über Optimierung
@section Überblick über Optimierung

Der wichtigste Teil, um ein System schnell zu machen, ist natürlich das
grundlegende Design. Ausserdem müssen Sie wissen, welche Dinge Ihr System
macht und was die Flaschenhälse sind.

Die wichtigsten Flaschenhälse sind:
@itemize @bullet
@item Suchvorgänge auf Festplatte.
Die Festplatte benötigt Zeit, um ein Stück Daten zu finden. Bei modernen
Festplatten (Stand: 1999) ist die mittlere Zugriffszeit üblicherweise
weniger als 10 ms, daher können theoretisch etwa 1.000 Suchvorgänge pro
Sekunde durchgeführt werden. Bei neueren Festplatten wird diese Zeit
allmählich besser. Für einzelne Tabellen ist sie sehr schwer zu optimieren.
Eine Möglichkeit, das zu optimieren, besteht darin, Daten auf mehr als eine
Platte zu verteilen.

@item Lesen von / Schreiben auf Festplatte.
Wenn die Festplatte in der richtigen Position ist, um die Daten zu lesen,
die wir brauchen, kann sie bei modernen Platten (Stand: 1999) etwas 10 bis
20 MB pro Sekunde heraus geben. Das ist leichter zu optimieren als
Suchvorgänge, weil man von mehrfachen Festplatten parallel lesen kann.

@item CPU-Zyklen.
Wenn die Daten im Hauptspeicher sind (oder bereits dort waren), müssen sie
verarbeitet werden, um das Ergebnis zu erhalten. Kleine Tabellen im
Vergleich zum Arbeitsspeicher ist der Faktor, der am meisten begrenzt. Auf
der anderen Seite ist Geschwindigkeit bei kleinen Tabellen üblicherweise
nicht das Problem.

@item Speicher-Bandbreite.
Wenn der Prozessor mehr Daten braucht, als in den CPU-Cache passen, wird
die Bandbreite des Hauptspeichers zum Flaschenhals. Auf den meisten
Systemen ist das ein ungewöhnlicher Flaschenhals, aber man sollte sich
dessen bewusst sein.
@end itemize




@menu
* Design Limitations::          
* Portability::                 
* Internal use::                
* MySQL Benchmarks::            
* Custom Benchmarks::           
@end menu

@node Design Limitations, Portability, Optimise Overview, Optimise Overview
@c German node Design-Einschränkungen
@subsection MySQL-Design-Einschränkungen

@cindex Design, Einschränkungen
@cindex Einschränkungen, Design

Weil MySQL extrem schnelles Tabellensperren beherrscht (mehrfache Leser /
einzelne Schreiber), ist das größte verbleibende Problem eine Mischung aus
einem laufenden Strom von Einfügevorgängen und langsamen Selects auf
dieselbe Tabelle.

Wir glauben, dass diese Wahl auf einer sehr großen Anzahl von Systemen
letztlich einen Gewinn darstellt. Auch dieser Fall ist üblicherweise
dadurch zu lösen, dass man mehrfache Kopien der Tabelle vorhält, aber man
benötigt mehr Anstrengung und Hardware.

Wir arbeiten auch an einigen Erweiterungen, um dieses Problem in Hinsicht
auf einige häufige Applikationsnischen zu lösen.


@node Portability, Internal use, Design Limitations, Optimise Overview
@c German node Portabilität
@subsection Portabilität

@cindex Portabilität
@cindex Crash-me-Programm
@cindex Programme, Crash-me

Weil alle SQL-Server unterschiedliche Teile von SQL implementieren, ist es
immer Arbeit, portable SQL-Applikationen zu schreiben. Bei sehr einfachen
Selects und Inserts ist das sehr einfach, aber je mehr Sie brauchen, desto
schwieriger wird es. Wenn Sie eine Applikation wollen, die bei vielen
Datenbanken noch schnell läuft, wird es sogar noch schwieriger!

Um eine komplexe Applikation portabel zu machen, müssen Sie sich für eine
Reihe von SQL-Servern entscheiden, mit denen sie funktionieren soll.

Sie können das MySQL-Crash-me-Programm bzw. die Webpage
@uref{http://www.mysql.com/information/crash-me.php} benutzen, um
Funktionen, Typen und Einschränkungen zu finden, die Sie mit einer Auswahl
von Datenbank-Servern benutzen können. Crash-me testet bei weitem nicht
alles, was möglich ist, aber mit etwa 450 unterschiedlichen Dingen ist es
recht umfassend.

Sie sollten zum Beispiel keine Spaltennamen benutzen, die länger als 10
Zeichen sind, wenn Sie auch Informix oder DB2 benutzen wollen.

Sowohl die MySQL-Benchmarks als auch die Crash-me-Programme sind sehr 
Datenbank-abhängig. Indem Sie einen Blick darauf werfen, wie wir damit
umgegangen sind, bekommen Sie ein Gefühl dafür, was Sie in Ihrer
Applikation schreiben müssen, damit diese Datenbank-unabhängig läuft. Die
Benchmark-Tests selbst befinden sich im @file{sql-bench}-Verzeichnis der
MySQL-Quelldistribution. Sie sind in Perl mit der
DBI-Datenbank-Schnittstelle geschrieben (die den Zugriffsteil des Problems
löst).

Siehe @uref{http://www.mysql.com/information/benchmarks.html} wegen der
Ergebnisse aus diesem Benchmark-Test.

Wie Sie an den Ergebnissen sehen, haben alle Datenbanken einige
Schwachpunkte, das heißt, sie haben verschiedene Design-Kompromisse, die
zu unterschiedlichem Verhalten führen.

Wenn Sie nach Datenbank-Unabhängigkeit streben, müssen Sie ein gutes Gefühl
für die Flaschenhälse jedes SQL-Servers bekommen. MySQL ist SEHR schnell
beim Abrufen und Aktualisieren von Dingen, hat aber Probleme, wenn
gleichzeitig langsame Leser / Schreiber auf dieselbe Tabelle zugreifen.
Oracle hat ein großes Problem, wenn Sie versuchen, auf Zeilen zuzugreifen,
der kürzlich aktualisiert wurden (solange, bis sie auf Platte
zurückgeschrieben wurden). Transaktionale Datenbanken sind allgemein nicht
sehr gut darin, Zusammenfassungstabellen aus Log-Tabellen zu erzeugen, weil
in diesem Fall Sperren auf Zeilenebene fast nutzlos ist.

Um Ihre Applikation @emph{wirklich} Datenbank-unabhängig zu machen, müssen
Sie eine leicht erweiterbare Schnittstelle definieren, über die Sie Ihre
Daten manipulieren. Weil auf den meisten Systemen C++ verfügbar ist, ist es
sinnvoll, C++-Klassen als Schnittstellen zu den Datenbanken zu benutzen.

Wenn Sie irgend ein spezifisches Feature einer Datenbankbenutzung (wie den
@code{REPLACE}-Befehl in MySQL), sollten Sie eine Methode für die anderen
SQL-Server codieren, um dasselbe Feature (wenngleich langsamer) zu
implementieren. Bei MySQL können Sie die @code{/*!  */}-Syntax benutzen, um
MySQL-spezifische Schlüsselwörter in einer Anfrage zu verwenden. Der Code
innerhalb von @code{/**/} wird von den meisten anderen SQL-Servern als
Kommentar behandelt (ignoriert).

Wenn WIRKLICH hohe Performance wichtiger als Exaktheit ist, wie bei einigen
Web-Applikationen, besteht eine Möglichkeit darin, eine Applikationsebene
zu erzeugen, die alle Ergebnisse cachet, um Ihnen noch höhere Performance
zu bringen. Indem Sie alte Ergebnisse nach einer Weile 'auslaufen' lassen,
können Sie den Cache in vernünftiger Weise 'frisch' halten. Das ist in
Fällen extrem hoher Last recht nett, wobei Sie den Cache dynamisch
vergrößern und die Verfallszeit (Expire Timeout) höher setzen können, bis
wieder Normalauslastung eintritt.

In diesem Fall sollte die Tabellenerzeugungsinformation Informationen über
die ursprüngliche Cache-Größe enthalten und darüber, wie oft die Tabelle
normalerweise aktualisiert (refresh) werden sollte.


@node Internal use, MySQL Benchmarks, Portability, Optimise Overview
@c German node Interner Gebrauch
@subsection Wofür benutzen wir MySQL?

@cindex Gebrauch, von MySQL
@cindex Kunden, von MySQL

In der anfänglichen Phase der Entwicklung von MySQL wurden die Features von
MySQL für unseren größten Kunden gemacht. Dieser macht Data-Warehousing
für eine Reihe der größten Einzelhändler in Schweden.

Aus allen Verkaufsstellen erhalten wir wöchentliche Zusammenfassungen aller
Bonuskarten-Transaktionen, und es wird erwartet, dass daraus nützliche
Informationen für die Eigentümer der Verkaufsstellen zur Verfügung gestellt
werden, damit diese herausfinden können, wie ihre Werbemaßnahmen ihre
Kunden beeinflussen.

Die Datenmenge ist recht riesig (etwa 7 Millionen
Zusammenfassungs-Transaktionen pro Monat), und wir haben Daten von 4 bis 10
Jahren, die wir dem Benutzer präsentieren müssen. Wir bekamen wöchentliche
Anfragen von Kunden, die 'sofortigen' Zugriff auf neue Berichte aus diesen
Daten wollten.

Die Lösung bestand darin, alle Informationen monatsweise in komprimierten
'Transaktions-' Tabellen zu speichern. Wir haben einen Satz einfacher
Makros (ein Skript), die aus diesen Tabellen Zusammenfassungstabellen
erzeugen, die nach verschiedenen Kriterien gruppiert sind (Produktgruppe,
Kunden-ID, Verkaufsstelle usw.). Die Berichte sind Web-Seiten, die
dynamisch durch ein kleines Perl-Skript erzeugt werden, das eine Web-Seite
parst, die enthaltenen SQL-Statements ausführt und die Ergebnisse einfügt.
Wir hätten statt dessen PHP oder mod_perl benutzt, aber diese waren damals
noch nicht verfügbar.

Für grafische Darstellungen schrieben wir ein einfaches Werkzeug in
@code{C}, das GIFs auf der Grundlage der Ergebnisse einer SQL-Anfrage
erzeugen kann (nach einigem Verarbeiten des Ergebnisses). Dieses wird
ebenfalls dynamisch durch ein Perl-Skript ausgeführt, das die
@code{HTML}-Dateien parst.

In den meisten Fällen kann ein neuer Bericht einfach durch das Kopieren
eines bestehenden Skripts und das Verändern der SQL-Anfrage darin erzeugt
werden. In einigen Fällen müssen wir einer bestehenden
Zusammenfassungstabelle weitere Felder hinzufügen oder eine neue
generieren, aber auch das ist recht einfach, weil wir alle
Transaktionstabellen auf Platte haben. (Momentan haben wir mindestens 50 GB
an Transaktionstabellen und 200 GB weiterer Kundendaten.)

Wir lassen unsere Kunden auch direkt mit ODBC auf die Transaktionstabellen
zugreifen, so dass fortgeschrittene Benutzer selbst mit den Daten
experimentieren können.

Wir hatten mit der Handhabung keinerlei Probleme, auf einer recht
bescheidenen Sun Ultra SPARCstation (2x200 MHz). Kürzlich haben wir einen
unserer Server auf eine mit 2 Prozessoren bestückte 400 MHz-UltraSPARC
erweitert und planen jetzt, Transaktionen auf Produktebene zu handhaben,
was eine zehnfache Steigerung der Datenmenge bedeuten würde. Wir glauben,
dass wir auch damit Schritt halten können, indem wir unseren Systemen
einfach mehr Festplattenplatz hinzufügen.

Wir experimentieren auch mit Intel-Linux, um in der Lage zu sein, mehr
CPU-Power preisgünstiger zu erhalten. Jetzt, wo wir das binäre portable
Datenbankformat haben (neu seit Version 3.23), werden wir dieses für einige
Teile der Applikation benutzen.

Unser anfängliches Gefühl sagt uns, dass Linux viel besser bei geringer bis
mittlerer Last ist, während Solaris wegen der extremen
Festplatten-Eingabe-/Ausgabe-Geschwindigkeit (Disk-IO) bei Hochlast besser
ist, aber wir können noch nichts Endgültiges darüber aussagen. Nach einigen
Diskussionen mit den Linux-Kernel-Entwicklern ist das eventuell ein
Seiteneffekt von Linux, das dem Stapel-Job so viel Ressourcen gibt, dass
die interaktive Performance sehr gering wird. Dadurch scheint die Maschine
sehr langsam und unempfänglich für Eingaben zu lassen, während große
Stapel-Jobs abgearbeitet werden. Wir hoffen, dass dies in zukünftigen
Linux-Kernels besser gehandhabt wird.


@node MySQL Benchmarks, Custom Benchmarks, Internal use, Optimise Overview
@c German node MySQL-Benchmarks
@subsection Die MySQL-Benchmark-Suite

@cindex Benchmark-Suite
@cindex Crash-me-Programm

Dieser Abschnitt sollte eine technische Beschreibung der MySQL-
Benchmark-Suite (und von @code{crash-me}) enthalten, aber diese
Beschreibung wurde noch nicht geschrieben. Momentan können Sie eine gute
Idee über den Benchmark bekommen, wenn Sie einen Blick auf den Code und die
Ergebnisse im @file{sql-bench}-Verzeichnis jeder MySQL-Quelldistribution
werfen.

Diese Benchmark-Suite ist als Benchmark gedacht, der jedem Benutzer
mitteilt, welche Dinge in einer gegebenen SQL-Implementation gut performen
und welche schlecht.

Beachten Sie, dass dieser Benchmark single-threaded ist. Daher misst er die
minimale Zeit der Operationen. In Zukunft planen wir, auch etliche
multi-threaded Test hinzuzufügen.

Beispiele (die auf derselben NT-4.0-Maschine liefen):

@multitable @columnfractions .6 .2 .2
@strong{2.000.000 Zeilen vom Index lesen} @tab @strong{Sekunden} @tab @strong{Sekunden}
@item mysql             @tab 367 @tab 249
@item mysql_odbc	@tab 464
@item db2_odbc		@tab 1206
@item informix_odbc	@tab 121126
@item ms-sql_odbc	@tab 1634
@item oracle_odbc	@tab 20800
@item solid_odbc	@tab 877
@item sybase_odbc	@tab 17614
@end multitable

@multitable @columnfractions .6 .2 .2
@strong{350.768 Zeilen einfügen} @tab @strong{Sekunden} @tab @strong{Sekunden}
@item mysql		@tab 381 @tab 206
@item mysql_odbc	@tab 619
@item db2_odbc		@tab 3460
@item informix_odbc	@tab 2692
@item ms-sql_odbc	@tab 4012
@item oracle_odbc	@tab 11291
@item solid_odbc	@tab 1801
@item sybase_odbc	@tab 4802
@end multitable

Im obigen Test lief MySQL mit einem 8 MB Index-Cache.

Weitere Benchmark-Ergebnisse haben wir unter
@uref{http://www.mysql.com/information/benchmarks.html} gesammelt.

Beachten Sie, dass Oracle nicht beinhaltet ist, weil sie gebeten haben,
entfernt zu werden. Alle Oracle-Benchmarks müssen von Oracle freigegeben
werden! Wir glauben, dass das die Aussagefähigkeit von Oracle-Benchmarks 
@strong{SEHR} zweifelhaft erscheinen läßt, weil alle obigen Benchmarks
dafür da sind zu zeigen, was eine Standard-Installation bei einem einzelnen
Client machen kann.

Um eine Benchmark-Suite laufen zu lassen, müssen Sie eine
MySQL-Quelldistribution herunter laden, den Perl-DBI-Treiber und den
Perl-DBD-Treiber für die gewünschte Datenbank installieren und dann
folgendes tun:

@example
cd sql-bench
perl run-all-tests --server=#
@end example

Wobei # einer der unterstützten Server ist. Sie erhalten eine Auflistung
aller Optionen und unterstützten Server, indem Sie @code{run-all-tests
--help} ausführen.

@cindex Crash-me
@code{Crash-me} versucht herauszufinden, welche Features eine Datenbank
unterstützt und wo ihre Fähigkeiten und Einschränkungen sind, indem
tatsächliche Anfragen ausgeführt werden. Beispielsweise stellt es fest:

@itemize @bullet
@item
Welche Spaltentypen unterstützt werden.
@item
Wie viele Indexe unterstützt werden.
@item
Welche Funktionen unterstützt werden.
@item
Wie Groß eine Anfrage sein kann.
@item
Wie Groß eine @code{VARCHAR}-Spalte sein kann.
@end itemize

Sie finden die Ergebnisse von Crash-me für viele verschiedene Datenbanken
unter @uref{http://www.mysql.com/information/crash-me.php}.


@node Custom Benchmarks,  , MySQL Benchmarks, Optimise Overview
@c German node Benutzerspezifische Benchmarks
@subsection Wie Sie Ihre eigenen Benchmarks benutzen

@cindex Benchmarks
@cindex Performance, Benchmarks

Sie sollten Ihre Applikation und Datenbank auf jeden Fall einem
Benchmark-Test unterziehen um herauszufinden, wo Flaschenhälse sind. Indem
Sie einen Flaschenhals beseitigen (oder ihn durch ein 'Dummy-Modul'
ersetzen), können Sie leicht den nächsten Flaschenhals herausfinden (usw.).
Selbst wenn die insgesamte Performance für Ihre Applikation ausreichend
ist, sollten Sie zumindest einen Plan für jeden Flaschenhals aufstellen und
entscheiden, auf welche Weise dieser beseitigt werden soll, wenn Sie eines
Tages die zusätzliche Performance benötigen.

Als Beispiel für ein portables Benchmark-Programm schauen Sie sich die
MySQL-Benchmark-Suite an. @xref{MySQL Benchmarks, , MySQL-Benchmarks}. Sie
können jedes Programm dieser Suite nehmen und es Ihren Bedürfnissen
entsprechend abändern. Wenn Sie das tun, können Sie unterschiedliche
Lösungen für Ihr Problem finden und testen, was bei Ihnen wirklich die
schnellste Lösung ist.

Es ist häufig der Fall, dass Probleme nur dann auftreten, wenn das System
unter schwerer Last läuft. Viele Kunden nahmen mit uns Kontakt auf, nachdem
sie ein (getestetes) System in eine Produktionsumgebung stellten und
Lastprobleme bekamen. Bei jedem dieser Fälle gab es bislang entweder
Probleme mit dem Grund-Design (Tabellen-Scans laufen NICHT gut unter hoher
Last) oder im Zusammenhang mit dem Betriebssystem / den Bibliotheken. Das
meiste davon wäre @strong{SEHR} viel einfacher zu beheben, wenn die Systeme
nicht bereits in einer Produktionsumgebung liefen.

Um solcherlei Probleme zu vermeiden, sollten Sie einige Anstrengung darauf
verwenden, Ihre gesamte Applikation unter der schlimmstmöglichen Last zu
benchmarken! Hierfür können Sie Super Smack benutzen, das Sie hier
erhalten:
@uref{http://www.mysql.com/downloads/super-smack/super-smack-1.0.tar.gz}.
Wie der Name nahelegt, kann es Ihr System auf die Knie zwingen, wenn Sie
das wollen. Achten Sie daher darauf, es nur auf Entwicklungssystemen zu
verwenden.


@node Query Speed, Locking Issues, Optimise Overview, MySQL Optimisation
@c German node Anfragen-Geschwindigkeit
@section @code{SELECT}s und andere Anfragen optimieren

@cindex Anfragen, Geschwindigkeit von
@cindex Berechtigungsprüfungen, Auswirkung auf Geschwindigkeit
@cindex Geschwindigkeit, von Anfragen

Zunächst etwas, das alle Anfragen betrifft: Je komplexer das
Berechtigungssystem, das Sie einrichten, desto mehr Overhead bekommen Sie.

Falls Sie noch keinerlei @code{GRANT}-Statements ausgeführt haben,
optimiert MySQL die Berechtigungsprüfung zum Teil. Wenn Sie also sehr hohe
Zugriffszahlen haben, kann es einen Zeitvorteil darstellen, Grants zu
vermeiden. Ansonsten können mehr Berechtigungsprüfungen in einem größeren
Overhead resultieren.

Wenn Sie Probleme bei einer bestimmten MySQL-Funktion haben, können Sie den
Zeitbedarf jederzeit wie folgt mit dem MySQL-Client feststellen:

@example
mysql> select benchmark(1000000,1+1);
+------------------------+
| benchmark(1000000,1+1) |
+------------------------+
|                      0 |
+------------------------+
1 row in set (0.32 sec)
@end example

Das Ergebnis zeigt, dass MySQL 1.000.000 @code{+}-Operationen in 0,32
Sekunden auf einer @code{PentiumII-400MHz}-Maschine ausführen kann.

Alle MySQL-Funktionen sollten sehr optimiert sein, aber es mag einige
Ausnahmen geben und @code{benchmark(schleifenzaehler,ausdruck)} ist ein
großartiges Werkzeug, um herauszufinden, ob das das Problem bei Ihrer
Anfrage darstellt.



@menu
* EXPLAIN::                     
* Estimating performance::      
* SELECT speed::                
* Where optimisations::         
* DISTINCT optimisation::       
* LEFT JOIN optimisation::      
* LIMIT optimisation::          
* Insert speed::                
* Update speed::                
* Delete speed::                
* Tips::                        
@end menu

@node EXPLAIN, Estimating performance, Query Speed, Query Speed
@c German node EXPLAIN
@subsection @code{EXPLAIN}-Syntax (Informationen über ein @code{SELECT} erhalten)

@findex EXPLAIN
@findex SELECT, Optimierung

@example
     EXPLAIN tabelle
oder EXPLAIN SELECT select_optionen
@end example

@code{EXPLAIN tabelle} ist ein Synonym für @code{DESCRIBE tabelle} oder
@code{SHOW COLUMNS FROM tabelle}.

Wenn Sie einem @code{SELECT}-Statement das Schlüsselwort @code{EXPLAIN}
voran stellen, erklärt MySQL explains, wie er das @code{SELECT} ausführen
würde, indem Informationen darüber gemacht werden, wie Tabellen verknüpft
(Join) werden und in welcher Reihenfolge.

Mit der Hilfe von @code{EXPLAIN} können Sie erkennen, wo Sie Tabellen
Indexe hinzufügen müssen, um ein schnelleres @code{SELECT} zu erhalten, das
Indexe benutzt, um die Datensätze zu finden. Ausserdem sehen Sie, ob der
Optimierer die Tabellen in optimaler Reihenfolge verknüpft. Um den
Optimierer zu zwingen, eine spezielle Verknüpfungsreihenfolge bei einem
@code{SELECT}-Statement einzuhalten, fügen Sie eine
@code{STRAIGHT_JOIN}-Klausel hinzu.

Bei nicht einfachen Verknüpfungen (Joins) gibt @code{EXPLAIN} für jede
Tabelle, die im @code{SELECT}-Statement benutzt wurde, eine
Informationszeile zurück. Die Tabellen sind in der Reihenfolge aufgelistet,
in der sie gelesen werden würden. MySQL löst alle Joins mit einer
Single-Sweep-Multi-Join-Methode auf. Das bedeutet, dass MySQL eine Zeile
aus der ersten Tabelle liest, dann die passende Zeile in der zweiten
Tabelle sucht, dann in der dritten Tabelle usw. Wenn alle Tabellen
verarbeitet wurden, gibt er die ausgewählten Spalten aus und geht
rückwärts durch die Tabellenliste durch, bis eine Tabelle gefunden wird,
bei der es weitere passende Zeilen gibt. Die nächste Zeile wird aus dieser
Tabelle gelesen, und der Prozess fährt mit der nächsten Tabelle fort.

Die Ausgabe von @code{EXPLAIN} enthält folgende Spalten:

@table @code
@item table
Die Tabelle, auf die sich die Ausgabezeile bezieht.

@item type
Der Join-Typ. Informationen über die verschiedenen Typen finden Sie weiter
unten.

@item possible_keys
Die @code{possible_keys}-Spalte gibt an, welche Indexe MySQL verwenden
konnte, um Zeilen in dieser Tabelle zu finden. Beachten Sie, dass diese
Spalte völlig unabhängig von der Reihenfolge der Tabellen ist. Das heißt,
dass einige der Schlüssel in possible_keys möglicherweise bei der
tatsächlich verwendeten Tabellenreihenfolge nicht verwendbar sind.

Wenn diese Spalte leer ist, gibt es keine relevanten Indexe. In diesem Fall
können Sie die Performance Ihrer Anfrage womöglich verbessern, indem Sie
die @code{WHERE}-Klausel untersuchen, um festzustellen, ob diese auf eine
oder mehrere Spalten verweist, die zweckmäßigerweise indiziert werden
sollten. Wenn das der Fall ist, erzeugen Sie einen entsprechenden Index und
prüfen Sie die Anfrage noch einmal mit @code{EXPLAIN}. @xref{ALTER TABLE}.

Um zu sehen, welche Indexe eine Tabelle hat, benutzen Sie @code{SHOW INDEX
FROM tabelle}.

@item key
@c German FIX changed @xref to @ref
Die @code{key}-Spalte gibt den Schlüssel an, den MySQL tatsächlich benutzen
wird. Der Schlüssel ist @code{NULL}, wenn kein Index gewählt wurde. Wenn
MySQL den falschen Index wählt, können Sie ihn wahrscheinlich zwingen,
einen anderen Index zu nehmen, indem Sie @code{myisamchk --analyze} oder
@ref{myisamchk syntax} ausführen oder @code{USE INDEX/IGNORE INDEX}
benutzen. @xref{JOIN}.

@item key_len
Die @code{key_len}-Spalte gibt die Länge des Schlüssels an, den MySQL
benutzen wird. Die Länge ist @code{NULL}, wenn @code{key} @code{NULL} ist.
Beachten Sie, dass Ihnen das angibt, wie viele Teile eines mehrteiligen
Schlüssels MySQL tatsächlich benutzen wird.

@item ref
Die @code{ref}-Spalte zeigt an, welche Spalten oder Konstanten beim
@code{key} benutzt werden, um Zeilen aus der Tabelle auszuwählen.

@item rows
die @code{rows}-Spalte gibt die Anzahl von Zeilen an, von denen MySQL
annimmt, dass es sie untersuchen muss, um die Anfrage auszuführen.

@item Extra
Diese Spalte enthält zusätzliche Informationen darüber, wie MySQL die
Anfrage auflösen wird. Folgende unterschiedliche Text-Zeichenketten können
in dieser Spalte stehen:

@table @code
@item Distinct
MySQL wird die Suche nach weiteren Zeilen für die aktuelle
Zeilenkombination nicht fortsetzen, nachdem er die erste passende Zeile
gefunden hat.

@item Not exists
MySQL war in der Lage, eine @code{LEFT JOIN}-Optimierung der Anfrage
durchzuführen, und wird keine weiteren Spalten in dieser Tabelle für die
vorherige Zeilenkombination mehr untersuchen, nachdem er eine Zeile
gefunden hat, die den @code{LEFT JOIN}-Kriterien entspricht.

Hier ist ein Beispiel dafür:

@example
SELECT * FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.id IS NULL;
@end example

Angenommen, @code{t2.id} ist mit @code{NOT NULL} definiert. In diesem Fall
scannt MySQL @code{t1} und schlägt die Zeilen in @code{t2} über
@code{t1.id} nach. Wenn MySQL eine übereinstimmende Zeile in @code{t2}
findet, weiß er, dass @code{t2.id} nie @code{NULL} sein kann und scannt
nicht durch den Rest der Zeilen in @code{t2}, die dieselbe @code{id} haben.
Mit anderen Worten, für jede Zeile in @code{t1} muss MySQL nur ein einziges
Mal in @code{t2} nachschlagen, unabhängig davon, wie viel übereinstimmende
Zeilen es in @code{t2} gibt.

@item @code{range checked for each record (index map: #)}
MySQL hat keinen gut geeigneten Index zum Benutzen gefunden. Statt dessen
wird er für jede Zeilenkombination in der vorherigen Tabelle eine Prüfung
vornehmen, welchen Index er benutzen soll (falls überhaupt) und diesen
Index benutzen, um Zeilen aus der Tabelle abzurufen. Das ist nicht sehr
schnell, aber immer noch schneller, als einen Join ohne Index
durchzuführen.

@item Using filesort
MySQL braucht einen zusätzlichen Durchgang, um herauszufinden, wie die
Zeilen in sortierter Reihenfolge abgerufen werden sollen. Die Sortierung
wird durchgeführt, indem in Abhängigkeit vom @code{join type} durch alle
Zeilen durchgegangen wird und der Sortierschlüssel und Zeiger auf die
Zeilen für alle Zeilen gespeichert wird, die dem @code{WHERE} entsprechen.
Danach werden die Schlüssel sortiert. Schließlich werden die Zeilen in
sortierter Reihenfolge abgerufen.

@item Using index
Die Spalteninformation wird aus der Tabelle abgerufen, indem nur
Informationen aus dem Index-Baum benutzt werden, ohne dass zum Suchen
zusätzlich in den tatsächlichen Zeilen gelesen werden muss. Das kann
gemacht werden, wenn alle benutzten Spalten der Tabelle Teil desselben
Indexes sind.

@item Using temporary
Um die Anfrage aufzulösen muss MySQL eine temporäre Tabelle erzeugen, die
das Ergebnis enthält. Das passiert typischerweise, wenn Sie ein @code{ORDER
BY} auf eine andere Spalte setzen als auf die, die Sie im @code{GROUP BY}
angegeben haben.

@item Where used
Eine @code{WHERE}-Klausel wird benutzt, um zu begrenzen, bei welchen Zeilen
auf Übereinstimmung in der nächsten Tabelle gesucht wird oder welche Zeilen
an den Client geschickt werden. Wenn Sie diese Information nicht haben und
die Tabelle vom Typ @code{ALL} oder @code{index} ast, ist vielleicht in
Ihrer Anfrage etwas falsch (falls Sie nicht vorhaben, alle Zeilen aus der
Tabelle zu holen / zu untersuchen).
@end table

Wenn Sie wollen, dass Ihre Anfragen so schnell wie möglich laufen, sollten
Sie auf @code{Using filesort} und @code{Using temporary} achten.
@end table

Die verschiedenen Join-Typen sind unten aufgeführt, sortiert vom besten zum
schlechtesten Typ:

@cindex Systemtabelle
@cindex Tabellen, System-
@table @code
@item system
Die Tabelle hat nur eine Zeile (= Systemtabelle). Das ist ein spezieller
Fall des @code{const}-Join-Typs.

@cindex Konstanten-Tabelle
@cindex Tabellen, Konstanten-
@item const
Die Tabelle hat höchsten eine übereinstimmende Zeile, die am Anfang der
Anfrage gelesen werden wird. Weil es nur eine Zeile gibt, können
Spaltenwerte in dieser Zeile vom Optimierer als Konstanten betrachtet
werden. @code{const}-Tabellen sind sehr schnell, weil sie nur einmal
gelesen werden!

@item eq_ref
Aus dieser Tabelle wird für jede Zeilenkombination der vorherigen Tabellen
eine Zeile gelesen. Das ist der bestmögliche Join-Typ, ausgenommen die
@code{const}-Typen. Er wird benutzt, wenn alle Teile eines Indexes vom Join
benutzt werden und der Index @code{UNIQUE} oder ein @code{PRIMARY KEY} ist.

@item ref
Alle Zeilen mit übereinstimmenden Index-Werten werden für jede
Zeilenkombination der vorherigen Tabellen gelesen. @code{ref} wird benutzt,
wenn der Join nur das am weitesten links stehende Präfix des Schlüssels
benutzt, oder wenn der Schlüssel nicht @code{UNIQUE} oder ein @code{PRIMARY
KEY} ist (mit anderen Worten, wenn der Join auf der Grundlage des
Schlüsselwerts keine einzelne Zeile auswählen kann). Wenn der Schlüssel,
der benutzt wird, nur mit einigen wenigen Zeilen übereinstimmt, ist dieser
Join-Typ gut.

@item range
Nur Zeilen, die innerhalb eines angegebenen Bereichs sind, werden abrufen,
wobei ein Index benutzt wird, um die Zeilen auszuwählen. Die
@code{key}-Spalte gibt an, welcher Index benutzt wird. @code{key_len}
enthält den längsten Schlüsselteil, der benutzt wurde. Die
@code{ref}-Spalte ist für diesen Typ NULL.

@item index
Das ist dasselbe wie @code{ALL}, ausser dass nur der Index-Baum gescannt
wird. Das ist üblicherweise schneller als @code{ALL}, weil die Index-Datei
üblicherweise kleiner ist als die Daten-Datei.

@item ALL
Für jede Zeilenkombination der vorherigen Tabellen wird ein kompletter
Tabellenscan durchgeführt. Das ist normalerweise nicht gut, wenn die
Tabelle die erste Tabelle ist, die nicht als @code{const} gekennzeichnet
ist, und üblicherweise @strong{sehr} schlecht in allen anderen Fällen. Sie
können @code{ALL} normalerweise vermeiden, indem Sie mehr Indexe
hinzufügen, so dass die Zeile auf der Grundlage der Konstanten-Werte oder
Spaltenwerte von früheren Tabellen abgerufen werden kann.
@end table

Sie erhalten einen guten Anhaltspunkt, wie gut ein Join ist, wenn Sie alle
Werte in der @code{rows}-Spalte der @code{EXPLAIN}-Ausgabe multiplizieren.
Das sollte grob aussagen, wie vielen Zeilen MySQL untersuchen muss, um die
Anfrage auszuführen. Diese Anzahl wird auch benutzt, wenn Sie Anfragen mit
der @code{max_join_size}-Variablen begrenzen.
@xref{Server parameters}.

Das folgende Beispiel zeigt, wie ein @code{JOIN} progressiv optimiert
werden kann, indem die Informationen genutzt werden, die @code{EXPLAIN}
bereit stellt.

Angenommen, Sie haben unten stehendes @code{SELECT}-Statement, das Sie mit
@code{EXPLAIN} untersuchen:

@example
EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
            tt.ProjectReference, tt.EstimatedShipDate,
            tt.ActualShipDate, tt.ClientID,
            tt.ServiceCodes, tt.RepetitiveID,
            tt.CurrentProcess, tt.CurrentDPPerson,
            tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
            et_1.COUNTRY, do.CUSTNAME
        FROM tt, et, et AS et_1, do
        WHERE tt.SubmitTime IS NULL
            AND tt.ActualPC = et.EMPLOYID
            AND tt.AssignedPC = et_1.EMPLOYID
            AND tt.ClientID = do.CUSTNMBR;
@end example

Nehmen wir bei diesem Beispiel folgendes an:

@itemize @bullet
@item
Die Spalten, die verglichen werden, wurden wie folgt deklariert:

@multitable @columnfractions .1 .2 .7
@item @strong{Tabelle} @tab @strong{Spalte} @tab @strong{Spaltentyp}
@item @code{tt}      @tab @code{ActualPC}      @tab @code{CHAR(10)}
@item @code{tt}      @tab @code{AssignedPC}    @tab @code{CHAR(10)}
@item @code{tt}      @tab @code{ClientID}      @tab @code{CHAR(10)}
@item @code{et}      @tab @code{EMPLOYID}      @tab @code{CHAR(15)}
@item @code{do}      @tab @code{CUSTNMBR}      @tab @code{CHAR(15)}
@end multitable

@item
Die Tabellen haben die unten stehenden Indexe:

@multitable @columnfractions .1 .9
@item @strong{Tabelle} @tab @strong{Index}
@item @code{tt}      @tab @code{ActualPC}
@item @code{tt}      @tab @code{AssignedPC}
@item @code{tt}      @tab @code{ClientID}
@item @code{et}      @tab @code{EMPLOYID} (primary key)
@item @code{do}      @tab @code{CUSTNMBR} (primary key)
@end multitable

@item
Die @code{tt.ActualPC}-Werte sind nicht gleichmäßig verteilt.
@end itemize

Anfangs, bevor die Optimierung durchgeführt wurde, ergab das
@code{EXPLAIN}-Statement folgende Informationen:

@example
table type possible_keys                key  key_len ref  rows  Extra
et    ALL  PRIMARY                      NULL NULL    NULL 74
do    ALL  PRIMARY                      NULL NULL    NULL 2135
et_1  ALL  PRIMARY                      NULL NULL    NULL 74
tt    ALL  AssignedPC,ClientID,ActualPC NULL NULL    NULL 3872
      range checked for each record (key map: 35)
@end example

Weil @code{type} bei jeder Tabelle @code{ALL} ist, zeigt die Ausgabe, dass
MySQL eine komplette Verknüpfung (Full Join) aller Tabellen durchführt! Das
dauert recht lange, weil das Produkt der Zeilenanzahl in jeder Tabelle
untersucht werden muss! In diesem Fall ist das @code{74 * 2.135 * 74 *
3.872 = 45.268.558.720} Zeilen. Wenn die Tabellen größer wären, können Sie
sich vorstellen, wie lange das dauern würde.

Ein Problem liegt hier darin, dass MySQL (noch) keine Indexe auf Spalten
effizient benutzen kann, wenn sie unterschiedlich deklariert sind. In
diesem Zusammenhang sind @code{VARCHAR} und @code{CHAR} dasselbe, es sei
denn, sie sind mit unterschiedlichen Längen deklariert. Weil
@code{tt.ActualPC} als @code{CHAR(10)} und @code{et.EMPLOYID} als
@code{CHAR(15)} deklariert ist, gibt eine Unstimmigkeit der Längen.

Um diese Ungleichheit der Spaltenlängen zu beheben, benutzen Sie
@code{ALTER TABLE}, um @code{ActualPC} von 10 auf 15 Zeichen zu verlängern:

@example
mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);
@end example

Jetzt sind @code{tt.ActualPC} und @code{et.EMPLOYID} beide
@code{VARCHAR(15)}. Eine erneute Ausführung des @code{EXPLAIN}-Statements
ergibt dieses Ergebnis:

@example
table type   possible_keys   key     key_len rew         rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL 3872    where used
do    ALL    PRIMARY         NULL    NULL    NULL        2135
      range checked for each record (key map: 1)
et_1  ALL    PRIMARY         NULL    NULL    NULL        74
      range checked for each record (key map: 1)
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC 1
@end example

Das ist nicht perfekt, aber viel besser (das Produkt der @code{rows}-Werte
ist jetzt um einen Faktor 74 niedriger). Diese Version wird innerhalb von
ein paar Sekunden ausgeführt.

Eine zweite Änderung kann durchgeführt werden, um die Unstimmigkeit der
Spaltenlängen für die @code{tt.AssignedPC = et_1.EMPLOYID}- und
@code{tt.ClientID = do.CUSTNMBR}-Vergleiche zu beheben:

@example
mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
                      MODIFY ClientID   VARCHAR(15);
@end example

Jetzt ergibt @code{EXPLAIN} folgende Ausgabe:

@example
table type   possible_keys   key     key_len rew            rows     Extra
et    ALL    PRIMARY         NULL    NULL    NULL           74
tt    rew    AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1
@end example

Das ist fast so gut, wie es überhaupt geht.

Das verbleibende Problem besteht darin, dass MySQL vorgabemäßig annimmt,
dass die Werte in der @code{tt.ActualPC}-Spalte gleichmäßig verteilt sind,
was in der @code{tt}-Tabelle nicht der Fall ist. Glücklicherweise ist es
einfach, MySQL darüber zu informieren:

@example
shell> myisamchk --analyze PFAD_ZU_MYSQL_DATENBANK/tt
shell> mysqladmin refresh
@end example

Jetzt ist der Join perfekt und @code{EXPLAIN} ergibt dieses Ergebnis:

@example
table type   possible_keys   key     key_len ref            rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL    3872    where used
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC    1
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1
@end example

Beachten Sie, dass die @code{rows}-Spalte in der Ausgabe von @code{EXPLAIN}
eine gehobene Form von Vermutung des MySQL-Join-Optimierers ist. Um eine
Anfrage zu optimieren, sollten Sie überprüfen, ob diese Zahlen der Wahrheit
nahe kommen. Wenn nicht, erhalten Sie eventuell bessere Performance, wenn
Sie @code{STRAIGHT_JOIN} in Ihrem @code{SELECT}-Statement benutzen und
versuchen, die Tabellen in der @code{FROM}-Klausel in anderer Reihenfolge
anzugeben.


@node Estimating performance, SELECT speed, EXPLAIN, Query Speed
@c German node Performance abschätzen
@subsection Anfragen-Performance abschätzen

@cindex abschätzen, Anfragen-Performance
@cindex Anfragen, Performance abschätzen
@cindex Performance, abschätzen

In den meisten Fällen können Sie die Performance schätzen, indem Sie
Suchvorgänge auf Festplatte zählen. Bei kleinen Tabellen können Sie die
Zeile üblicherweise mit 1 Festplatten-Suchvorgang finden (weil der Index
wahrscheinlich im Cache ist). Bei größeren Tabellen können Sie schätzen,
dass Sie (bei der Benutzung von B++-Baum-Indexen) brauchen werden:
@code{log(zeilen_zahl) / log(index_block_laenge / 3 * 2 / (index_laenge +
daten_zeiger_laenge)) + 1} Suchvorgänge, um die Zeile zu finden.

In MySQL ist ein Index-Block üblicherweise 1024 Bytes lang und der
Daten-Zeiger üblicherweise 4 Bytes. Eine 500.000-Zeilen-Tabelle mit einer
Indexlänge von 3 (medium integer) ergibt:
@code{log(500.000)/log(1024/3*2/(3+4)) + 1} = 4 Suchvorgänge.

Da der obige Index etwa 500.000 * 7 * 3/2 = 5,2 MB benötigen würde
(angenommen, dass die Index-Puffer zu 2/3 gefüllt sind, was ein typischer
Wert sit), haben Sie wahrscheinlich viel vom Index im Arbeitsspeicher und
werden wahrscheinlich nur 1 bis 2 Betriebssystem-Aufrufe benötigen, um
Daten zu lesen, um die Zeile zu finden.

Bei Schreibvorgängen brauchen Sie jedoch 4 Suchanfragen (wie oben), um
herauszufinden, wo der neue Index platziert wird, und normalerweise 2
Suchvorgänge, um den Index zu aktualisieren und die Zeile zu schreiben.

Beachten Sie, dass oben Gesagtes nicht bedeutet, dass Ihre Applikation
allmählich mit N log N verfällt! Solange alles durch das Betriebssystem
oder den SQL-Server gecachet wird, werden die Dinge nur marginal langsamer,
wenn die Tabellen größer werden. Wenn die Daten zu Groß werden, um
gecachet zu werden, werden die Dinge anfangen, viel langsamer zu laufen,
bis Ihre Applikation schließlich komplett durch Suchvorgänge auf
Festplatte ausgebremst wird (die mit N log N zunehmen). Um das zu
vermeiden, vergrößern Sie den Index-Cache, wenn die Daten wachsen.
@xref{Server parameters}.


@node SELECT speed, Where optimisations, Estimating performance, Query Speed
@c German node SELECT-Geschwindigkeit
@subsection Geschwindigkeit von @code{SELECT}-Anfragen

@findex SELECT-Geschwindigkeit

@cindex Geschwindigkeit, von Anfragen

Wenn Sie ein langsames @code{SELECT ... WHERE} schneller machen wollen, ist
im Allgemeinen das erste, was zu prüfen ist, ob Sie einen Index hinzufügen
können oder nicht. @xref{MySQL indexes, , MySQL-Indexe}. Alle Verweise
(Reference) zwischen verschiedenen Tabellen sollten üblicherweise mit
Indexen gemacht werden. Sie können den @code{EXPLAIN}-Befehl benutzen, um
herauszufinden, welche Indexe für ein @code{SELECT} benutzt werden.
@xref{EXPLAIN, , @code{EXPLAIN}}.

Einige allgemeine Tipps:

@itemize @bullet
@item
Um MySQL zu helfen, Anfragen besser zu optimieren, lassen Sie
@code{myisamchk --analyze} auf eine Tabelle laufen, nachdem sie mit
relevanten Daten gefüllt wurde. Das aktualisiert einen Wert für jeden
Index-Teil, der die durchschnittliche Anzahl von Zeilen angibt, die
denselben Wert haben. (Bei eindeutigen Indexen ist das natürlich immer 1).
MySQL benutzt diesen Wert, um zu entscheiden, welcher Index benutzt werden
soll, wenn Sie zwei Tabellen mit einem 'nicht konstanten Ausdruck'
verbinden. Sie können das Ergebnis nach dem Laufenlassen von @code{analyze}
mit @code{SHOW INDEX FROM tabelle} überprüfen und die
@code{Cardinality}-Spalte untersuchen.

@item
Um einen Index und Daten gemäß einem Index zu sortieren, benutzen Sie
@code{myisamchk --sort-index --sort-records=1} (wenn Sie nach Index 1
sortieren wollen). Wenn Sie einen eindeutigen Index haben, von dem Sie alle
Datensätze gemäß der Reihenfolge dieses Indexes lesen wollen, ist das eine
gute Art, das schneller zu machen. Beachten Sie jedoch, dieses Sortieren
nicht optimal geschrieben wird und bei einer großen Tabelle lange dauert!
@end itemize


@node Where optimisations, DISTINCT optimisation, SELECT speed, Query Speed
@c German node WHERE-Optimierung
@subsection Wie MySQL @code{WHERE}-Klauseln optimiert

@findex WHERE

@cindex Optimierungen

Die @code{WHERE}-Optimierungen wurden hier in den @code{SELECT}-Teil
aufgenommen, weil sie meist in Verbindung mit @code{SELECT} benutzt werden,
aber dieselben Optimierungen treffen für @code{WHERE} bei @code{DELETE}-
und @code{UPDATE}-Statements zu.

Beachten Sie auch, dass dieser Abschnitt nicht vollständig ist. MySQL führt
viele Optimierungen durch und wir hatten noch keine Zeit, alle davon zu
dokumentieren.

Einige der Optimierungen, die MySQL durchführt, sind unten aufgeführt:

@itemize @bullet
@item
Entfernung unnötiger Klammern:
@example
   ((a AND b) AND c OR (((a AND b) AND (c AND d))))
-> (a AND b AND c) OR (a AND b AND c AND d)
@end example
@item
Konstanten-'Falten' (Folding):
@example
   (a<b AND b=c) AND a=5
-> b>5 AND b=c AND a=5
@end example
@item
Bedingungsentfernung bei Konstanten (notwendig wegen Konstanten-'Falten'):
@example
   (B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6)
-> B=5 OR B=6
@end example
@item
Konstante Ausdrücke, die von Indexen benutzt werden, werden nur einmal
ausgewertet.
@item
@code{COUNT(*)} auf eine einzelne Tabelle ohne ein @code{WHERE} wird direkt
aus der Tabelleninformation abgerufen. Das wird auch bei jeglichen
@code{NOT NULL}-Ausdrücken gemacht, wenn diese nur für eine Tabelle benutzt
werden.
@item
Früherkennung ungültiger Konstanten-Ausdrücke. MySQL stellt schnell fest,
dass einige @code{SELECT}-Statements unmöglich sind, und gibt keine Zeilen
zurück.
@item
@code{HAVING} wird mit @code{WHERE} vereinigt, wenn Sie @code{GROUP BY}
oder Gruppen-Funktionen (@code{COUNT()}, @code{MIN()} usw.) nicht
benutzen.
@item
Für jeden Sub-Join wird ein einfacheres @code{WHERE} konstruiert, um eine
schnelle @code{WHERE}-Evaluierung für jeden Sub-Join zu erzielen, und auch,
um Datensätze so bald wie möglich überspringen zu können.
@cindex Konstanten-Tabelle
@cindex Tabellen, Konstanten-
@item
Alle Konstanten-Tabellen werden zuerst gelesen, vor jeder anderen Tabelle
in der Anfrage. Eine Konstanten-Tabelle ist:
@itemize @minus
@item
Eine leere Tabelle oder eine Tabelle mit 1 Zeile.
@item
Eine Tabelle, die bei einer @code{WHERE}-Klausel auf einen
@code{UNIQUE}-Index oder einen @code{PRIMARY KEY} benutzt wird, wobei alle
Index-Teile mit konstanten Ausdrücken benutzt werden und die Index-Teile
als @code{NOT NULL} definiert sind.
@end itemize
Alle folgenden Tabellen werden als Konstanten-Tabellen benutzt:
@example
mysql> SELECT * FROM t WHERE primary_key=1;
mysql> SELECT * FROM t1,t2
           WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
@end example

@item
Die beste Join-Kombination, um Tabellen zu verknüpfen, wird gefunden, wenn
man alle Möglichkeiten probiert. Wenn alle Spalten in @code{ORDER BY} und
in @code{GROUP BY} aus derselben Tabelle stammen, wird diese Tabelle
vorzugsweise vorn hingestellt, wenn verknüpft wird.
@item
Wenn es eine @code{ORDER BY}-Klausel und eine andere @code{GROUP
BY}-Klausel gibt, oder wenn @code{ORDER BY} oder @code{GROUP BY} Spalten
aus Tabellen enthält, die nicht aus der ersten Tabelle in der Join-Reihe
stammen, wird eine temporäre Tabelle erzeugt.
@item
Wenn Sie @code{SQL_SMALL_RESULT} benutzen, benutzt MySQL eine temporäre
Tabelle im Arbeitsspeicher.
@item
Jeder Tabellen-Index wird abgefragt und der beste Index, der weniger als
30% der Zeilen überspannt, wird benutzt. Wenn ein solcher Index nicht
gefunden werden kann, wird ein schneller Tabellenscan benutzt.
@item
In einigen Fällen kann MySQL Zeilen vom Index lesen, ohne überhaupt in der
Daten-Datei nachzuschlagen. Wenn alle Spalten, die vom Index benutzt
werden, numerisch sind, wird nur der Index-Baum benutzt, um die Anfrage
aufzulösen.
@item
Bevor jeder Datensatz herausgegeben wird, werden die, die nicht mit der
@code{HAVING}-Klausel übereinstimmen, übersprungen.
@end itemize

Einige Beispiele von Anfragen, die sehr schnell sind:

@example
mysql> SELECT COUNT(*) FROM tabelle;
mysql> SELECT MIN(schluessel_teil1),MAX(schluessel_teil1) FROM tabelle;
mysql> SELECT MAX(schluessel_teil2) FROM tabelle
           WHERE schluessel_teil_1=konstante;
mysql> SELECT ... FROM tabelle
           ORDER BY schluessel_teil1,schluessel_teil2,... LIMIT 10;
mysql> SELECT ... FROM tabelle
           ORDER BY schluessel_teil1 DESC,schluessel_teil2 DESC,... LIMIT 10;
@end example

Die folgenden Anfragen werden aufgelöst, indem nur der Index-Baum benutzt
wird (unter der Annahme, dass die indizierten Spalten numerisch sind):

@example
mysql> SELECT schluessel_teil1,schluessel_teil2 FROM tabelle WHERE schluessel_teil1=val;
mysql> SELECT COUNT(*) FROM tabelle
           WHERE schluessel_teil1=val1 AND schluessel_teil2=val2;
mysql> SELECT schluessel_teil2 FROM tabelle GROUP BY schluessel_teil1;
@end example

Die folgenden Anfragen benutzen Indexierung, um die Zeilen in sortierter
Reihenfolge abzufragen, ohne einen separaten Sortierdurchgang:

@example
mysql> SELECT ... FROM tabelle ORDER BY schluessel_teil1,schluessel_teil2,... ;
mysql> SELECT ... FROM tabelle ORDER BY schluessel_teil1 DESC,schluessel_teil2 DESC,... ;
@end example


@node DISTINCT optimisation, LEFT JOIN optimisation, Where optimisations, Query Speed
@c German node DISTINCT-Optimierung
@subsection Wie MySQL @code{DISTINCT} optimiert

@findex DISTINCT

@cindex Optimierung, DISTINCT

@code{DISTINCT} wird für alle Spalten in @code{GROUP BY} umgewandelt,
@code{DISTINCT} in Kombination mit @code{ORDER BY} benötigt in vielen
Fällen ebenfalls eine temporäre Tabelle.

Wenn @code{LIMIT #} mit @code{DISTINCT} kombiniert wird, hält MySQL an,
sobald er @code{#} eindeutige Zeilen findet.

Wenn Sie nicht Spalten aus allen benutzten Tabellen verwenden, hält MySQL
mit dem Scannen der nicht benutzten Tabellen an, sobald er die erste
Übereinstimmung gefunden hat.

@example
SELECT DISTINCT t1.a FROM t1,t2 where t1.a=t2.a;
@end example

Im Beispiel wird angenommen, dass t1 vor t2 benutzt wird (überprüfen Sie
das mit @code{EXPLAIN}). In diesem Fall hört MySQL auf, von t2 zu lesen
(für diese bestimmte Zeile in t1), sobald die erste Zeile in t2 gefunden
wurde.


@node LEFT JOIN optimisation, LIMIT optimisation, DISTINCT optimisation, Query Speed
@c German node LEFT-JOIN-Optimierung
@subsection Wie MySQL @code{LEFT JOIN} optimiert

@findex LEFT JOIN

@cindex Optimierung, LEFT JOIN

@code{A LEFT JOIN B} ist in MySQL wie folgt implementiert:

@itemize @bullet
@item
Die Tabelle @code{B} wird als abhängig von Tabelle @code{A} und allen
Tabellen, von denen @code{A} abhängig ist, gesetzt.

@item
Die Tabelle @code{A} wird als abhängig von allen Tabellen (ausser @code{B})
gesetzt, die in der @code{LEFT JOIN}-Bedingung aufgeführt sind.

@item
Alle @code{LEFT JOIN}-Bedingungen werden zu @code{WHERE}-Klausel
verschoben.

@item
Alle Standard-Join-Optimierungen werden durchgeführt, mit der Ausnahme,
dass eine Tabelle immer nach allen Tabellen gelesen wird, von denen sie
abhängig ist. Wenn es eine zirkuläre Abhängigkeit gibt, gibt MySQL einen
Fehler aus.

@item
Alle Standard-@code{WHERE}-Optimierungen werden durchgeführt.

@item
Wenn es eine Zeile in @code{A} gibt, die mit der @code{WHERE}-Klausel
übereinstimmt, aber keine Zeile in @code{B}, die mit der @code{LEFT
JOIN}-Bedingung übereinstimmt, wird eine zusätzliche Zeile für @code{B}
erzeugt, deren Spalten alle auf @code{NULL} gesetzt sind.

@item
Wenn Sie @code{LEFT JOIN} benutzen, um Zeilen zu finden, die in einer
Tabelle nicht existieren, und Sie folgendes im @code{WHERE}-Teil angeben:
@code{spalten_name IS NULL}, wobei spalten_name eine Spalte ist, die als
@code{NOT NULL} deklariert ist, hört MySQL mit der Suche nach weiteren
Zeilen auf (für eine bestimmte Schlüsselkombination), nachdem er eine Zeile
gefunden hat, die mit der @code{LEFT JOIN}-Bedingung übereinstimmt.
@end itemize

@code{RIGHT JOIN} ist analog zu @code{LEFT JOIN} implementiert.

Die Lese-Reihenfolge der Tabellen, die von @code{LEFT JOIN} und
@code{STRAIGHT JOIN} erzwungen wird, hilft dem Optimierer (der berechnet,
in welcher Reihenfolge die Tabellen verknüpft werden sollen), seine Arbeit
schneller durchzuführen, weil weniger Tabellenvertauschungen überprüft
werden müssen.

Beachten Sie, dass das oben Gesagte bedeutet, dass bei einer Anfrage des
folgenden Typs:

@example
SELECT * FROM a,b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
@end example

MySQL einen kompletten Scan von @code{b} durchführen wird, weil der
@code{LEFT JOIN} erzwingt, dass diese vor @code{d} gelesen wird.

Das läßt sich in diesem Fall beheben, indem die Anfrage wie folgt geändert
wird:

@example
SELECT * FROM b,a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d (d.key=a.key) WHERE b.key=d.key
@end example


@node LIMIT optimisation, Insert speed, LEFT JOIN optimisation, Query Speed
@c German node LIMIT-Optimierung
@subsection Wie MySQL @code{LIMIT} optimiert

@findex LIMIT

@cindex Optimierung, LIMIT

In einigen Fällen handhabt MySQL die Anfrage unterschiedlich, wenn Sie
@code{LIMIT #} statt @code{HAVING} benutzen:

@itemize @bullet
@item
Wenn Sie nur einige wenige Zeilen mit @code{LIMIT} auswählen, benutzt MySQL
in einigen Fällen Indexe, wenn er ansonsten vorzugsweise einen
vollständigen Tabellenscan durchführen würde.
@item
Wenn Sie @code{LIMIT #} mit @code{ORDER BY} benutzen, beendet MySQL das
Sortieren, sobald er die ersten @code{#} Zeilen gefunden hat, anstatt die
gesamte Tabelle zu sortieren.
@item
Wenn Sie @code{LIMIT #} mit @code{DISTINCT} kombinieren, hört MySQL auf,
sobald er @code{#} eindeutige Zeilen gefunden hat.
@item
In einigen Fällen kann @code{GROUP BY} aufgelöst werden, indem der
Schlüssel in der Reihenfolge gelesen wird (oder der Schlüssel sortiert
wird) und danach Zusammenfassungen berechnet werden, bis sich der
Schlüsselwert ändert. In diesem Fall berechnet @code{LIMIT #} keine
unnötigen @code{GROUP BY}'s.
@item
Sobald MySQL die ersten @code{#} Zeilen an den Client geschickt hat, wird
die Anfrage abgebrochen.
@item
@code{LIMIT 0} gibt immer schnell eine leere Ergebnismenge (empty set)
zurück. Das ist nützlich, um die Anfrage zu überprüfen und die Spaltentypen
der Ergebnisspalten zu erhalten.
@item
Die Größe der temporären Tabellen benutzt @code{LIMIT #}, um zu berechnen,
wieviel Platz benötigt wird, um die Anfrage aufzulösen.
@end itemize


@node Insert speed, Update speed, LIMIT optimisation, Query Speed
@c German node INSERT-Geschwindigkeit
@subsection Geschwindigkeit von @code{INSERT}-Anfragen

@findex INSERT

@cindex Geschwindigkeit, beim Einfügen
@cindex Einfügen, Geschwindigkeit

Die Zeit, einen Datensatz einzufügen, besteht ungefähr aus:

@itemize @bullet
@item
Verbindung:                     (3)
@item
Anfrage an den Server schicken: (2)
@item
Anfrage parsen:                 (2)
@item
Datensatz einfügen:             (1 x Größe des Datensatzes)
@item
Indexe einfügen:                (1 x Anzahl der Indexe)
@item
Schließen:                     (1)
@end itemize

Wobei die Zahlen in etwa proportional zur Gesamtzeit sind. Diese Berechnung
zieht den anfänglichen Overhead, um Tabellen zu öffnen, nicht in Betracht
(was einmal für jede gleichzeitig laufende Anfrage gemacht wird).

Die Größe der Tabelle verlangsamt das Einfügen von Indexen um N log N
(B-Bäume).

Einige Möglichkeiten, die Geschwindigkeit von Einfügeoperationen zu
steigern:

@itemize @bullet
@item
Wenn Sie viele Zeilen vom selben Client aus zur gleichen Zeit einfügen,
benutzen Sie mehrfache Werte (Liste) im @code{INSERT}-Statements. Das geht
viel schneller (in manchen Fälle um Faktoren) als separate
@code{INSERT}-Statements zu benutzen. Tunen Sie die
@code{myisam_bulk_insert_tree_size}-Variable, um das sogar noch zu
beschleunigen. @xref{SHOW VARIABLES}.
@item
Wenn Sie viele Zeilen von unterschiedlichen Clients aus einfügen, können
Sie mehr Geschwindigkeit erzielen, wenn Sie das @code{INSERT
DELAYED}-Statement benutzen. @xref{INSERT, , @code{INSERT}}.
@item
Beachten Sie, dass Sie mit @code{MyISAM}-Tabellen Zeilen zur selben Zeit
einfügen können, zu der @code{SELECT}s laufen, wenn es keine gelöschten
Zeilen in den Tabellen gibt.
@item
Wenn Daten in eine Tabelle aus einer Textdatei eingeladen werden, benutzen
Sie @code{LOAD DATA INFILE}. Das ist üblicherweise 20 mal schneller als
viele @code{INSERT}-Statements zu benutzen. @xref{LOAD DATA, , @code{LOAD DATA}}.
@item
Mit etwas zusätzlicher Mühe ist es möglich, @code{LOAD DATA INFILE} noch
schneller laufen zu lassen, wenn die Tabelle viele Indexe hat. Gehen Sie
wie folgt vor:

@enumerate
@item
Optional erzeugen Sie die Tabelle mit @code{CREATE TABLE}, zum Beispiel mit
@code{mysql} oder über die Perl-DBI.

@item
Führen Sie ein @code{FLUSH TABLES}-Statement oder den Shell-Befehl
@code{mysqladmin flush-tables} aus.

@item
Geben Sie @code{myisamchk --keys-used=0 -rq /pfad/zu/db/tabelle} ein.
Dadurch entfernen Sie die Benutzung aller Indexe von der Tabelle.

@item
Fügen Sie Daten in die Tabelle mit @code{LOAD DATA INFILE} ein. Dadurch
werden keine Indexe aktualisiert, was deswegen sehr schnell läuft.

@item
Wenn Sie in Zukunft nur noch aus der Tabelle lesen, benutzen Sie
@code{myisampack}, um sie kleiner zu machen. @xref{Compressed format}.

@item
Erzeugen Sie die Indexe mit @code{myisamchk -r -q /pfad/zu/db/tabelle} neu.
Hierdurch wird der Index-Baum im Speicher erzeugt, bevor er auf die Platte
geschrieben wird, was viel schneller ist, weil viele Suchvorgänge auf
Platte vermieden werden. Der sich ergebende Index-Baum ist ausserdem
perfekt ausbalanciert.

@item
Führen Sie ein @code{FLUSH TABLES}-Statement oder den Shell-Befehl
@code{mysqladmin flush-tables} aus.
@end enumerate

Diese Prozedur wird in Zukunft in @code{LOAD DATA INFILE} eingebaut werden.

Ab @strong{MySQL 4.0} können Sie auch @code{ALTER TABLE tabelle DISABLE
KEYS} anstelle von @code{myisamchk --keys-used=0 -rq /pfad/zu/db/tabelle}
und @code{ALTER TABLE tabelle ENABLE KEYS} anstelle von @code{myisamchk -r
-q /pfad/zu/db/tabelle} benutzen. Damit können Sie auch die @code{FLUSH
TABLES}-Schritte überspringen.
@item
Sie können die Einfügegeschwindigkeit steigern, indem Sie Tabellen sperren:

@example
mysql> LOCK TABLES a WRITE;
mysql> INSERT INTO a VALUES (1,23),(2,34),(4,33);
mysql> INSERT INTO a VALUES (8,26),(6,29);
mysql> UNLOCK TABLES;
@end example

Der hauptsächliche Geschwindigkeitsunterschied liegt darin, dass der
Index-Puffer nur einmal auf Platte zurück geschrieben wird, nachdem alle
@code{INSERT}-Statements fertig sind. Normalerweise würden die Index-Puffer
so oft zurück geschrieben wie es @code{INSERT}-Statements gibt. Das Sperren
wird nicht benötigt, wenn Sie alle Zeilen mit einem einzigen Statement
einfügen können.

Durch das Sperren wird auch die Gesamtzeit von Tests auf mehrere
Verbindungen gesenkt, aber die maximale Wartezeit für einige Threads wird
erhöht (weil sie auf Sperren warten). Beispiel:

@example
Thread 1 führt 1000 Einfügevorgänge durch.
Thread 2, 3 und 4 fügen 1 Einfügevorgang durch.
Thread 5 führt 1000 Einfügevorgänge durch.
@end example

Wenn Sie kein Sperren benutzen, sind die Threads 2, 3 und 4 vor 1 und 5
fertig. Wenn Sie Sperren benutzen, sind 2, 3 und 4 wahrscheinlich nicht vor
1 oder 5 fertig, aber die Gesamtzeit sollte etwa 40% geringer sein.

Weil @code{INSERT}-, @code{UPDATE}- und @code{DELETE}-Operationen in MySQL
sehr schnell sind, erhalten Sie bessere Performance über alles, wenn Sie um
alles herum Sperren hinzufügen, was mehr als etwa 5 Einfügeoperationen oder
Aktualisierungen (Updates) in einer Zeile durchführt. Wenn Sie sehr viele
Einfügeoperationen in einer Zeile durchführen, können Sie ein @code{LOCK
TABLES} machen, gefolgt von einem gelegentlichen @code{UNLOCK TABLES}
(etwa alle 1.000 Zeilen), um anderen Threads zu gestatten, auf die Tabelle
zuzugreifen. Das Ergebnis wäre ebenfalls ein netter Geschwindigkeitsgewinn.

Natürlich ist @code{LOAD DATA INFILE} zum Einladen von Daten viel
schneller.
@end itemize

Um sowohl für @code{LOAD DATA INFILE} als auch für @code{INSERT} mehr
Geschwindigkeit zu erzielen, vergrößern Sie den Schlüssel-Puffer.
@xref{Server parameters}.


@node Update speed, Delete speed, Insert speed, Query Speed
@c German node UPDATE-Geschwindigkeit
@subsection Geschwindigkeit von @code{UPDATE}-Anfragen

Update-Anfragen werden wie eine @code{SELECT}-Anfrage optimiert, mit dem
zusätzlichen Overhead eines Schreibvorgangs. Die Geschwindigkeit des
Schreibvorgangs hängt von der Größe der Daten und von der Anzahl der
Indexe, die aktualisiert werden, ab. Indexe, die nicht geändert werden,
werden nicht aktualisiert.

Eine weitere Möglichkeit, Aktualisierungen (Updates) schnell zu machen,
ist, sie zu verzögern und dann später viele Aktualisierungen hintereinander
zu machen. Viele Aktualisierungen hintereinander sind viel schneller als
nur eine zugleich, wenn Sie die Tabelle sperren.

Beachten Sie, dass die Aktualisierung eines Datensatzes bei dynamischem
Datensatzformat dazu führen kann, dass der Datensatz aufgespalten wird.
Wenn Sie das oft durchführen, ist es daher sehr wichtig, gelegentlich
@code{OPTIMIZE TABLE} auszuführen. @xref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}}.


@node Delete speed, Tips, Update speed, Query Speed
@c German node DELETE-Geschwindigkeit
@subsection Geschwindigkeit von @code{DELETE}-Anfragen

Wenn Sie alle Zeilen in der Tabelle löschen wollen, sollten Sie
@code{TRUNCATE TABLE tabelle} benutzen. @xref{TRUNCATE}.

Die Zeit, die für das Löschen eines Datensatzes benötigt wird, ist exakt
proportional zur Anzahl der Indexe. Um Datensätze schneller zu löschen,
können Sie die Größe des Index-Caches herauf setzen.
@xref{Server parameters}.


@node Tips,  , Delete speed, Query Speed
@c German node Tipps
@subsection Weitere Optimierungstipps

@cindex Optimierung, Tipps
@cindex Tipps, Optimierung

Ungeordnete Liste von Tipps für schnellere Systeme:

@itemize @bullet
@item
Benutzen Sie persistente Verbindungen zur Datenbank, um
Verbindungs-Overhead zu vermeiden. Wenn Sie keine persistenten Verbindungen
benutzen können und viele neue Verbindungen zur Datenbank aufmachen,
sollten Sie den Wert der @code{Thread_cache_size}-Variablen ändern.
@xref{Server parameters}.
@item
Überprüfen Sie immer, dass alle Ihre Anfragen tatsächlich die Indexe
benutzen, die Sie in den Tabellen erzeugt haben. In MySQL kann man das mit
dem @code{EXPLAIN}-Befehl tun. @xref{EXPLAIN, Explain, Explain, Handbuch}.
@item
Versuchen Sie, komplexe @code{SELECT}-Anfragen auf Tabellen zu vermeiden,
die viel aktualisiert werden, um Probleme mit Tabellensperren zu vermeiden.
@item
Die neuen @code{MyISAM}-Tabellen können Zeilen in eine Tabelle ohne
gelöschte Zeile zur gleichen Zeit einfügen, wie eine andere Tabelle aus ihr
liest. Wenn das für Sie wichtig ist, sollten Sie Methoden in Betracht
ziehen, bei denen Sie keine Zeilen löschen müssen, oder @code{OPTIMIZE
TABLE} laufen lassen, nachdem Sie viele Zeilen gelöscht haben.
@item
Benutzen Sie @code{ALTER TABLE ... ORDER BY ausdruck1,ausdruck2,...}, wenn
Sie Zeilen zumeist in der Reihenfolge ausdruck1,ausdruck2,... abrufen. Wenn
Sie diese Option nach großen Änderungen in der Tabelle nutzen, erzielen
Sie eventuell höhere Performance.
@item
In einigen Fällen kann es sinnvoll sein, eine Spalte einzuführen, die auf
der Grundlage von Informationen aus anderen Spalten 'gehashed' ist. Wenn
diese Spalte kurz und halbwegs eindeutig ist, kann das schneller sein als
ein großer Index auf mehrere Spalten. In MySQL ist es sehr einfach, eine
solche zusätzliche Spalte zu benutzen:
@code{SELECT * FROM tabelle WHERE hash=MD5(concat(spalte1,spalte2))
AND spalte_1='constant' AND spalte_2='constant'}
@item
Bei Tabellen, die sich viel ändern, sollten Sie versuchen, alle
@code{VARCHAR}- oder @code{BLOB}-Spalten zu vermeiden. Sonst erhalten Sie
dynamische Zeilenlängen, sobald Sie eine einzige @code{VARCHAR}- oder
@code{BLOB}-Spalte verwenden. @xref{Table types}.
@item
Normalerweise nützt es nichts, eine Tabelle in verschiedene Tabellen
aufzuteilen, nur weil die Zeile 'viel' werden. Um auf eine Zeile
zuzugreifen, ist das wichtigste, was die Performance betrifft, der
Suchvorgang nach dem ersten Byte der Zeile auf der Platte. Nachdem die
Daten gefunden wurden, können die meisten neuen Platten die gesamte Zeile
für die meisten Applikationen schnell genug lesen. Der einzige Fall, wo es
wirklich etwas ausmacht, wenn eine Tabelle aufgeteilt wird, ist, wenn die
Tabelle dynamische Zeilenlänge hat (siehe oben), was nicht in eine feste
Zeilenlänge umgewandelt werden kann, oder wenn Sie die Tabelle sehr oft
scannen müssen, die meisten der Spalten hierfür aber nicht benötigen.
@xref{Table types}.
@item
Wenn Sie sehr oft etwas auf der Grundlage von Informationen aus sehr vielen
Zeilen berechnen müssen (zum Beispiel Dinge zählen), ist es wahrscheinlich
besser, eine neue Tabelle einzuführen und den Zähler in Echtzeit zu
aktualisieren. Eine Aktualisierung des Typs @code{UPDATE tabelle set
zaehler=zaehler+1 where index_spalte=konstante} ist sehr schnell!

Das ist sehr wichtig, wenn Sie Datenbanken wie MySQL benutzen, die nur
Tabellensperren haben (viele Leser / einzelne Schreiber). Bei den meisten
sonstigen Datenbanken ergibt das ebenfalls bessere Performance, weil der
Zeilensperr-Manager weniger zu tun haben wird.
@item
Wenn Sie Statistiken aus großen Log-Tabellen gewinnen wollen, benutzen Sie
Zusammenfassungstabellen, statt die gesamte Tabelle zu scannen. Die Wartung
der Zusammenfassungen sollte wesentlich leichter sein, als die Statistiken
'live' zu generieren. Es ist viel schneller, neue Zusammenfassungstabellen
aus den Logs zu erzeugen, wenn sich Dinge ändern (abhängig von
Geschäftsentscheidungen) als eine laufende Applikation ändern zu müssen!
@item
Wenn möglich sollte man Berichte als 'live' oder 'statistisch'
klassifizieren, wobei die Daten, die für statistische Berichte benötigt
werden, nur auf der Grundlage von Zusammenfassungstabellen erzeugt werden,
die aus den eigentlichen Daten generiert werden.
@item
Ziehen Sie Vorteile aus der Tatsache, dass Spalten Vorgabewerte haben.
Fügen Sie nur dann explizit Werte ein, wenn der einzufügende Wert vom
Vorgabewert abweicht. Das verringert das Parsen, das MySQL durchführen
muss, und erhöht die Einfügegeschwindigkeit.
@item
In einigen Fällen ist es bequem, Daten zu komprimieren und in einem Blob zu
speichern. In diesem Fall müssen Sie in Ihrer Applikation etwas
zusätzlichen Code unterbringen, um die Dinge im Blob zu packen bzw. zu
entpacken. Das kann aber in manchen Phasen etliches an Zugriffen einsparen.
Das ist praktisch, wenn Sie Daten haben, die mit einer statischen
Tabellenstruktur nicht konform sind.
@item
Normalerweise sollten Sie versuchen, alle Daten nicht redundant zu halten
(was sich in der Datenbanktheorie dritte Normalform nennt). Scheuen Sie
sich aber nicht davor, Dinge zu duplizieren oder Zusammenfassungstabellen
zu erzeugen, wenn Sie dies brauchen, um mehr Geschwindigkeit zu erzielen.
@item
Gespeicherte Prozeduren (Stored Procedures) oder UDF (user defined
functions, benutzerdefinierte Funktionen) sind eine gute Möglichkeit, mehr
Performance zu erzielen. Sie sollten jedoch immer eine andere (langsamere)
Möglichkeit parat haben, wenn Sie eine Datenbank benutzen, die gespeicherte
Prozeduren nicht unterstützt.
@item
Man erreicht immer etwas, wenn man Anfragen / Antworten in der Applikation
cachet und versucht, viele Einfüge- oder Aktualisierungsvorgänge zugleich
durchzuführen. Wenn Ihre Datenbank Tabellensperren unterstützt (wie MySQL
und Oracle), sollte das dazu führen, dass der Index-Cache nur einmal auf
Platte zurück geschrieben wird, nachdem alles Einfügen / Aktualisieren
ausgeführt ist.
@item
Benutzen Sie @code{INSERT /*! DELAYED */}, wenn Sie nicht wissen brauchen,
wann Ihre Daten geschrieben werden. Das erhöht die Geschwindigkeit, weil
viele Datensätze mit einem einzige Festplattenschreibzugriff geschrieben
werden können.
@item
Benutzten Sie @code{INSERT /*! LOW_PRIORITY */}, wenn Sie wollen, dass Ihre
Selects höhere Priorität haben.
@item
Benutzen Sie @code{SELECT /*! HIGH_PRIORITY */}, um zu bewirken, dass
Selects in der Wartereihe nach vorn springen. Das heißt, der Select wird
sogar dann durchgeführt, wenn jemand darauf wartet, etwas zu schreiben.
@item
Benutzen Sie das mehrzeilige @code{INSERT}-Statement, um viele Zeilen mit
einem SQL-Befehl zu speichern (viele SQL-Server unterstützen das).
@item
Benutzen Sie @code{LOAD DATA INFILE}, um größere Datenmengen zu laden. Das
ist schneller als normale Einfügevorgänge und wird noch schneller, wenn
@code{myisamchk} in @code{mysqld} integriert wird.
@item
Benutzen Sie @code{AUTO_INCREMENT}-Spalten, um eindeutige Werte zu
erzeugen.
@item
Benutzen Sie gelegentlich @code{OPTIMIZE TABLE}, um Fragmentierungen zu
vermeiden, wenn Sie das dynamische Tabellenformat verwenden.
@c German FIX changed @xref from TABLE to OPTIMIZE TABLE (point to proper node)
@xref{OPTIMIZE TABLE}.
@item
Benutzen Sie - wenn möglich - @code{HEAP}-Tabellen, um mehr Geschwindigkeit
zu erzielen. @xref{Table types}.
@item
Bei einer normalen Webserver-Konfiguration sollten Bilder als separate
Dateien gespeichert werden. Das heißt, speichern Sie nur einen Verweis zur
Datei in der Datenbank. Der Hauptgrund ist, dass normale Webserver viel
besser darin sind, Dateien zu cachen als Datenbankinhalte. Daher ist es
viel einfacher, ein schnelles System zu bekommen, wenn Sie Dateien
benutzen.
@item
Benutzen Sie für nicht kritische Daten, auf die oft zugegriffen wird,
Tabellen im Arbeitsspeicher (zum Beispiel Informationen über die Banner,
die Benutzern ohne Cookies zuletzt präsentiert wurden).
@item
Spalten mit identischen Informationen in unterschiedlichen Tabellen sollten
identisch deklariert sein und identische Namen haben. Vor Version 3.23
konnte man ansonsten langsame Joins erhalten.

Versuchen Sie, die Namen einfach zu halten (benutzen Sie @code{name}
anstelle von @code{kunde_name} in der Kundentabelle). Um Namen für andere
SQL-Server portabel zu halten, sollten Sie sie kürzer als 18 Zeichen
halten.
@item
Wenn Sie WIRKLICH hohe Geschwindigkeit brauchen, sollten Sie einen Blick
auf die Low-Level-Schnittstellen zur Datenspeicherung werfen, die die
unterschiedlichen SQL-Server unterstützen! Wenn Sie zum Beispiel auf
@code{MyISAM} direkt zugreifen, erhalten Sie eine
Geschwindigkeitssteigerung um den Faktor 2 bis 5, im Vergleich zur
Benutzung der SQL-Schnittstelle. Um das durchführen zu können, müssen die
Daten auf demselben Server liegen wie die Applikation und üblicherweise
sollte auf sie nur von einem Prozess zugegriffen werden (weil externes
Dateisperren reichlich langsam ist). Man könnte die oben genannten Probleme
beseitigen, indem Low-Level-@code{MyISAM}-Befehle in den MySQL-Server
eingebaut werden (das wäre eine einfache Möglichkeit, bei Bedarf mehr
Performance zu erlangen). Indem die Datenbankshnittstelle sorgfältig
entworfen wird, sollte es recht einfach sein, diese Arten von Optimierung
zu unterstützen.
@item
In vielen Fällen ist es schneller, auf Daten aus einer Datenbank (mit einer
direkten Verbindung) als über eine Textdatei zuzugreifen, schon deshalb,
weil die Datenbank wahrscheinlich kompakter ist als die Textdatei (wenn Sie
numerische Daten benutzen) und hierdurch weniger Festplattenzugriffe
erforderlich sind. Ausserdem wird Code eingespart, weil Sie Ihre
Textdateien nicht parsen müssen, um Zeilen- und Spaltenbegrenzungen zu
finden.
@item
Ausserdem können Sie Replikation benutzen, um die Geschwindigkeit zu
steigern. @xref{Replication}.
@item
Wenn eine Tabelle mit @code{DELAY_KEY_WRITE=1} deklariert wird, werden
Aktualisierungen auf Indexe schneller, weil diese nicht auf Platte
geschrieben werden, bis die Datei geschlossen wird. Der Nachteil ist, dass
Sie auf diesen Tabellen @code{myisamchk} laufen lassen sollten, bevor Sie
@code{mysqld} starten, um sicherzustellen, dass diese in Ordnung sind,
falls irgend etwas @code{mysqld} mittendrin killt. Weil die
Schlüssel-Informationen jederzeit aus den Daten erzeugt werden können,
sollten Sie durch @code{DELAY_KEY_WRITE} nichts verlieren.
@end itemize


@node Locking Issues, Optimising Database Structure, Query Speed, MySQL Optimisation
@c German node Sperren (Locks)
@section Sperren (Locking)




@menu
* Internal locking::            
* Table locking::               
@end menu

@node Internal locking, Table locking, Locking Issues, Locking Issues
@c German node Internes Sperren
@subsection Wie MySQL Tabellen sperrt

@cindex internes Sperren
@cindex sperren, Tabellen
@cindex Tabellen, sperren

Im Anhang finden Sie eine Erörterung zu den unterschiedlichen
Sperrmethoden. @xref{Locking methods}.

Jedes Sperren in MySQL ist blockierungsfrei. Das wird erreicht, indem alle
Sperren zugleich am Anfang einer Anfrage angefordert werden, und indem
Tabellen immer in derselben Reihenfolge gesperrt werden.

The Sperrmethode, die MySQL für @code{WRITE}-Sperren benutzt, funktioniert
wie folgt:

@itemize @bullet
@item
Falls es keine Sperren auf die Tabelle gibt, wird eine Schreibsperre
gemacht.
@item
Ansonsten wird die Sperranforderung in die Schreibsperren-Warteschlange
eingereiht.
@end itemize

Die Sperrmethode, die MySQL für @code{READ}Sperren benutzt, funktioniert
wie folgt:

@itemize @bullet
@item
Falls es keine Schreibsperren auf die Tabelle gibt, wird eine Lesesperre
gemacht.
@item
Ansonsten wird die Sperranforderung in die Lesesperren-Warteschlange
eingereiht.
@end itemize

Wenn eine Sperre aufgehoben wird, wird die Sperren den Threads in der
Schreibsperren-Warteschlange verfügbar gemacht, danach den Threads in der
Lesesperren-Warteschlange.

Das bedeutet, wenn Sie viele Aktualisierungen auf eine Tabelle haben,
warten @code{SELECT}-Statements, bis es keine Aktualisierungen mehr gibt.

Um das für den Fall zu umgehen, dass es viele @code{INSERT}-
und-@code{SELECT}-Operationen auf eine Tabelle gibt, können Sie Zeilen in
eine temporäre Tabelle einfügen und die echte Tabelle gelegentlich aus den
Daten der temporäre Tabelle aktualisieren.

Das machen Sie wie folgt:
@example
mysql> LOCK TABLES echte_tabelle WRITE, einfuege_tabelle WRITE;
mysql> insert into echte_tabelle select * von einfuege_tabelle;
mysql> TRUNCATE TABLE einfuege_tabelle;
mysql> UNLOCK TABLES;
@end example

Sie können bei @code{INSERT}, @code{UPDATE} oder @code{DELETE} die
@code{LOW_PRIORITY}-Option oder bei @code{SELECT} die
@code{HIGH_PRIORITY}-Option benutzen, wenn Sie dem Abruf von Daten in
bestimmten Fällen Priorität einräumen wollen. Sie können auch @code{mysqld}
mit @code{--low-priority-updates} starten, um dasselbe Verhalten zu
erreichen.

Die Benutzung von @code{SQL_BUFFER_RESULT} kann ebenfalls helfen,
Tabellensperren kürzer zu machen. @xref{SELECT}.

Sie können auch den Sperr-Code in @file{mysys/thr_lock.c} ändern, um eine
einzige Warteschlagen zu benutzen. In diesem Fall haben Schreibsperren und
Lesesperren dieselbe Priorität, was bei einigen Applikationen eventuell
hilfreich ist.


@node Table locking,  , Internal locking, Locking Issues
@c German node Tabellensperren
@subsection Themen, die Tabellensperren betreffen

@cindex Probleme, Tabellensperren

Der Tabellensperren-Code in MySQL ist blockierungsfrei.

MySQL benutzt Tabellensperren (anstelle von Zeilensperren oder
Spaltensperren) für alle Tabellentypen ausser @code{BDB}-Tabellen, um eine
sehr hohe Sperrgeschwindigkeit zu erzielen. Bei großen Tabellen ist
Tabellensperren bei den meisten Applikationen VIEL besser als
Zeilensperren, aber es gibt natürlich ein paar Fallstricke.

Bei @code{BDB}- und @code{InnoDB}-Tabellen benutzt MySQL Tabellensperren,
wenn Sie die Tabelle explizit mit @code{LOCK TABLES} sperren oder einen
Befehl ausführen, der jede Zeile in der Tabelle ändern wird, wie
@code{ALTER TABLE}. Bei diesen Tabellentypen empfehlen wir, @code{LOCK
TABLES} überhaupt nicht zu benutzen.

Ab MySQL-Version 3.23.7 können Sie Zeilen in @code{MyISAM}-Tabellen zur
gleichen Zeit einfügen, während andere Threads aus der Tabelle lesen.
Beachten Sie, dass das momentan nur funktioniert, wenn es zu der Zeit, zu
der das Einfügen vorgenommen wird, keine durch gelöschte Zeilen verursachte
Löcher in der Tabelle gibt. Wenn alle Löcher mit neuen Daten gefüllt
wurden, werden gleichzeitige Einfügevorgänge automatisch wieder aktiviert.

Tabellensperren ermöglicht, dass viele Threads gleichzeitig aus einer
Tabelle lesen, aber bevor ein Thread in die Tabelle schreiben kann, muss er
zunächst exklusiven Zugriff erhalten. Während der Aktualisierung müssen
andere Threads, die auf diese Tabelle zugreifen wollen, warten, bis die
Aktualisierung fertig ist.

Weil Aktualisierung von Tabellen normalerweise als wichtiger erachtet
werden als @code{SELECT}, erhalten alle Statements, die eine Tabelle
aktualisieren, eine höhere Priorität als Statements, die Informationen aus
der Tabelle abrufen. Das sollte sicherstellen, dass Aktualisierungen nicht
'verhungern', wenn viele große Anfragen auf eine bestimmte Tabelle
durchgeführt werden. (Sie können das ändern, indem Sie bei dem Statement,
dass die Aktualisierung durchführt, LOW_PRIORITY verwenden, oder beim
@code{SELECT}-Statement @code{HIGH_PRIORITY}.)

Ab MySQL-Version 3.23.7 können Sie die @code{max_write_lock_count}-Variable
benutzen, um MySQL zu zwingen, temporär allen @code{SELECT}-Statements, die
auf eine Tabelle warten, nach einer bestimmten Anzahl von Einfügevorgängen
auf eine Tabelle höhere Priorität einzuräumen.

Tabellensperren ist jedoch bei folgendem Szenario nicht sehr gut:

@itemize @bullet
@item
Ein Client führt ein @code{SELECT} aus, das lange Zeit läuft.
@item
Ein anderer Client führt danach ein @code{UPDATE} auf die benutzte Tabelle
aus. Dieser Client wartet, bis das @code{SELECT} fertig ist.
@item
Ein weiterer Client führt ein weiteres @code{SELECT}-Statement auf dieselbe
Tabelle aus. Weil @code{UPDATE} höhere Priorität als @code{SELECT} hat,
wartet dieses @code{SELECT}, bis das @code{UPDATE} fertig ist. Es wartet
auch darauf, dass das erste @code{SELECT} fertig ist!
@item
Ein Thread wartet bei etwas wie @code{Platte voll}. In diesem Fall warten
alle anderen Threads, die auf die problemverursachende Tabelle zugreifen
wollen, bis mehr Speicher verfügbar gemacht wurde.
@end itemize

Mögliche Lösungen dieses Problems sind:

@itemize @bullet
@item
Versuchen Sie, @code{SELECT}-Statements schneller ablaufen zu lassen.
Hierfür müssen Sie eventuell Zusammenfassungstabellen erzeugen.

@item
Starten Sie @code{mysqld} mit @code{--low-priority-updates}. Das gibt allen
Statements, die eine Tabelle aktualisieren (ändern), geringere Priorität
als einem @code{SELECT}-Statement. Im vorstehenden Szenario würde das
@code{SELECT}-Statement vor dem @code{INSERT}-Statement ausgeführt werden.

@item
Sie können auch einem bestimmten @code{INSERT}-, @code{UPDATE}- oder
@code{DELETE}-Statement mit dem @code{LOW_PRIORITY}-Attribut geringere
Priorität geben.

@item
Starten Sie @code{mysqld} mit einem niedrigen Wert für
@strong{max_write_lock_count}, um @code{READ}-Sperren nach einer bestimmten
Anzahl von @code{WRITE}-Sperren zu ermöglichen.

@item
Sie können festlegen, dass alle Aktualisierungen von einem bestimmten
Thread mit niedriger Priorität ausgeführt werden, indem Sie den SQL-Befehl
@code{SET SQL_LOW_PRIORITY_UPDATES=1} benutzen. @xref{SET OPTION, ,
@code{SET OPTION}}.

@item
Sie können mit dem @code{HIGH_PRIORITY}-Attribut festlegen, dass ein
bestimmtes @code{SELECT} sehr wichtig ist. @xref{SELECT, , @code{SELECT}}.

@item
Wenn Sie Probleme mit @code{INSERT} in Kombination mit @code{SELECT} haben,
stellen Sie auf die neuen @code{MyISAM}-Tabellen um, weil diese
gleichzeitige @code{SELECT}s und @code{INSERT}s unterstützen.

@item
Wenn Sie hauptsächlich @code{INSERT}- und @code{SELECT}-Statements mischen,
wird das @code{DELAYED}-Attribut für @code{INSERT} wahrscheinlich Ihre
Probleme lösen. @xref{INSERT, , @code{INSERT}}.

@item
Wenn Sie Probleme mit @code{SELECT} und @code{DELETE} haben, mag die
@code{LIMIT}-Option für @code{DELETE} helfen. @xref{DELETE, ,
@code{DELETE}}.
@end itemize


@node Optimising Database Structure, Optimising the Server, Locking Issues, MySQL Optimisation
@c German node Optimierung der Datenbank-Struktur
@section Optimierung der Datenbank-Struktur




@menu
* Design::                      
* Data size::                   
* MySQL indexes::               
* Indexes::                     
* Multiple-column indexes::     
* Open tables::                 
* Table cache::                 
* Creating many tables::        
@end menu

@node Design, Data size, Optimising Database Structure, Optimising Database Structure
@c German node Design
@subsection MySQL-Datenbank-Design-Überlegungen

@cindex Design, Überlegungen zum Datenbank-Design
@cindex Datenbank-Design
@cindex Speicherung von Daten

MySQL speichert Zeilendaten und Indexdaten in separaten Dateien. Viele
(fast alle) anderen Datenbanken vermischen Zeilen- und Indexdaten in
derselben Datei. Wir glauben, dass die Wahl, die MySQL getroffen hat, für
einen sehr weiten Bereich moderner Systeme besser ist.

Eine weitere Möglichkeit, Zeilendaten zu speichern, besteht darin, die
Information für jede Spalten in einem separaten Bereich zu halten
(Beispiele sind SDBM und Focus). Das verursacht Performance-Einbussen für
jede Anfrage, die auf mehr als eine Spalte zugreift. Weil das so schnell
schlechter wird, wenn auf mehr als eine Spalte zugegriffen wird, glauben
wir, dass dieses Modell für Mehrzweck-Datenbanken nicht gut ist.

Der häufigere Fall ist, dass Index und Daten zusammen gespeichert sind (wie
bei Oracle, Sybase usw.). In diesem Fall befindet sich die
Zeileninformation auf der Leaf-Page des Indexes. Das Gute daran ist, dass
man sich damit - abhängig davon, wie gut der Index gecachet ist - einen
Festplatten-Lesezugriff spart. Das Schlechte an diesem Layout sind
folgende Dinge:

@itemize @bullet
@item
Tabellenscannen geht viel langsamer, weil man durch alle Indexe lesen muss,
um an die Daten zu kommen.
@item
Man kann nicht nur die Index-Tabelle benutzen, um Daten einer Anfrage
abzurufen.
@item
Man verliert viel Speicherplatz, weil man Indexe von den Nodes duplizieren
muss (weil man die Zeile nicht in den Nodes speichern kann).
@item
Löschvorgänge werden die Tabelle im Zeitablauf zersetzen (weil Indexe in
Nodes üblicherweise bei Löschvorgängen nicht aktualisiert werden).
@item
Ist es schwieriger, NUR die Index-Daten zu cachen.
@end itemize


@node Data size, MySQL indexes, Design, Optimising Database Structure
@c German node Datengröße
@subsection Wie Sie Ihre Daten so klein wie möglich bekommen

@cindex Daten, Größe
@cindex verringern, Datengröße
@cindex Speicherplatz, minimieren
@cindex Tabellen, Performance verbessern
@cindex Performance, verbessern

Eine der grundlegendsten Optimierungen besteht darin, Ihre Daten (und
Indexe) dazu zu bekommen, dass sie möglichst wenige Platz auf der Platte
(und im Arbeitsspeicher) benutzen. Das kann zu gewaltigen Verbesserungen
führen, weil Lesezugriffe von der Platte schneller ablaufen und
normalerweise weniger Hauptspeicher benutzt wird. Das Indexieren nimmt
darüber hinaus weniger Ressourcen in Anspruch, wenn es auf kleinere Spalten
durchgeführt wird.

MySQL unterstützt viele verschiedene Tabellentypen und Zeilenformate. Wenn
Sie das richtige Tabellenformat benutzen, kann Ihnen das große
Performance-Gewinne bringen.
@xref{Table types}.

Sie erhalten bessere Performance auf eine Tabelle und minimieren den
benötigten Speicherplatz, wenn Sie die unten aufgeführten Techniken
verwenden:

@itemize @bullet
@item
Benutzen Sie die effizientesten (kleinsten) möglichen Typen. MySQL hat
viele spezialisierte Typen, die Plattenplatz und Arbeitsspeicher sparen.

@item
Benutzen Sie - falls möglich - die kleineren Ganzzahl-Typen, um kleinere
Tabellen zu erhalten. @code{MEDIUMINT} zum Beispiel ist oft besser als
@code{INT}.

@item
Deklarieren Sie Spalten - falls möglich - als @code{NOT NULL}. Das macht
alles schneller und Sie sparen ein Bit pro Spalte. Beachten Sie, dass, wenn
Sie wirklich @code{NULL} in Ihrer Applikation benötigen, Sie dieses
natürlich benutzen sollten. Vermeiden Sie nur, einfach alle Spalten
vorgabemäßig auf @code{NULL} zu haben.

@item
Wenn Sie keine Spalten variabler Länge haben (@code{VARCHAR}, @code{TEXT}
oder @code{BLOB}-Spalten), wird ein Festgrößenformat benutzt. Das ist
schneller, mag aber leider etwas Speicherplatz verschwenden.
@xref{MyISAM table formats}.

@item
Der primäre Index einer Tabelle sollte so kurz wie möglich sein. Das macht
die Identifikation einer Zeile schnell und effizient.

@item
Bei jeder Tabelle müssen Sie entscheiden, welche Speicher- / Index-Methode
benutzt werden soll. @xref{Table types}.

@item
Erzeugen Sie nur die Indexe, die Sie tatsächlich brauchen. Indexe sind gut
für das Abfragen von Daten, aber schlecht, wenn Sie Dinge schnell speichern
müssen. Wenn Sie meist auf eine Tabelle zugreifen, indem Sie nach einer
Kombination von Spalten suchen, legen Sie einen Index auf diese. Der erste
Index-Teil sollte die meistbenutzte Spalte sein. Wenn Sie IMMER viele
Spalten benutzen, sollten Sie die Spalte zuerst benutzen, die mehr
Duplikate hat, um eine bessere Kompression des Indexes zu erzielen.

@item
Wenn es sehr wahrscheinlich ist, dass eine Spalte ein eindeutiges Präfix
auf der ersten Anzahl von Zeichen hat, ist es besser, nur dieses Präfix zu
indexieren. MySQL unterstützt einen Index auf einem Teil einer
Zeichen-Spalte. Kürzere Indexe sind nicht nur schneller, weil sie weniger
Plattenplatz brauchen, sondern auch, weil Sie mehr Treffer im Index-Cache
erhalten und daher weniger Festplattenzugriffe benötigen.
@xref{Server parameters}.

@item
Unter manchen Umständen kann es vorteilhaft sein, eine Tabelle zu teilen,
die sehr oft gescannt wird. Das gilt insbesondere, wenn diese ein
dynamisches Tabellenformat hat und es möglich ist, durch die Zerlegung eine
kleinere Tabelle mit statischem Format zu erhalten, die benutzt werden
kann, um die relevanten Zeilen zu finden.
@end itemize


@node MySQL indexes, Indexes, Data size, Optimising Database Structure
@c German node MySQL-Indexe
@subsection Wie MySQL Indexe benutzt

@cindex Indexe, Benutzung von

Indexe werden benutzt, um Zeilen mit einem bestimmten Spaltenwert schnell
zu finden. Ohne Index müsste MySQL mit dem ersten Datensatz anfangen und
dann durch die gesamte Tabelle lesen, bis er die relevanten Zeilen findet.
Je größer die Tabelle, desto mehr Zeit kostet das. Wenn die Tabellen für
die infrage kommenden Zeilen einen Index hat, kann MySQL schnell eine
Position bekommen, um mitten in der Daten-Datei loszusuchen, ohne alle
Daten zu betrachten. Wenn eine Tabelle 1.000 Zeilen hat, ist das mindestens
100 mal schneller als sequentielles Lesen. Wenn Sie jedoch auf fast alle
1.000 Zeilen zugreifen müssen, geht sequentielles Lesen schneller, weil man
mehrfache Festplattenzugriffe einspart.

Alle MySQL-Indexe (@code{PRIMARY}, @code{UNIQUE} und @code{INDEX}) sind in
B-Bäumen gespeichert. Zeichenketten werden automatisch präfix-komprimiert,
ebenfalls werden Leerzeichen am Ende komprimiert.
@c German FIX unsplit @xref
@xref{CREATE INDEX, ,@code{CREATE INDEX}}.

Indexe werden benutzt, um:
@itemize @bullet
@item
Schnell die Zeilen zu finden, die mit einer @code{WHERE}-Klausel
übereinstimmen.

@item
Zeilen aus anderen Tabellen abzurufen, wenn Sie Joins durchführen.

@item
Den @code{MAX()}- oder @code{MIN()}-Wert für eine spezielle indizierte
Spalte zu finden. Das wird durch einen Präprozessor optimiert, der
überprüft, ob Sie @code{WHERE} schluessel_teil_# = constant auf allen
Schlüsselteilen < N verwenden. In diesem Fall führt MySQL ein einzige
Schlüsselnachschlagen durch und ersetzt den @code{MIN()}-Ausdruck mit einer
Konstanten. Wenn alle Ausdrücke durch Konstanten ersetzt sind, gibt die
Anfrage sofort ein Ergebnis zurück:

@example
SELECT MIN(schluessel_teil2),MAX(schluessel_teil2) FROM tabelle where schluessel_teil1=10
@end example

@item
Eine Tabelle zu sortieren oder zu gruppieren, wenn das Sortieren oder
Gruppieren mit dem am weitesten links stehenden Präfix eines benutzbaren
Schlüssels durchgeführt wird (zum Beispiel @code{ORDER BY
schluessel_teil_1,schluessel_teil_2}). Der Schlüssel wird in umgekehrter
Reihenfolge gelesen, wenn allen Schlüsselteilen @code{DESC} folgt.

Der Index kann auch benutzt werden, selbst wenn @code{ORDER BY} nicht exakt
mit dem Index übereinstimmt, solange alle unbenutzten Indexteile und alle
zusätzlichen @code{ORDER BY}-Spalten Konstanten in der @code{WHERE}-Klausel
sind. Folgende Anfragen werden einen Index benutzen, um den @code{ORDER
BY}-Teil aufzulösen:

@example
SELECT * FROM foo ORDER BY schluessel_teil1,schluessel_teil2,schluessel_teil3;
SELECT * FROM foo WHERE spalte=konstante ORDER BY spalte, schluessel_teil1;
SELECT * FROM foo WHERE schluessel_teil1=konstante GROUP BY schluessel_teil2;
@end example

@item
In einigen Fällen kann eine Anfrage so optimiert werden, dass Sie Werte
abruft, ohne in der Daten-Datei nachzuschlagen. Wenn alle benutzten Spalten
einer Tabelle numerisch sind und ein ganz links stehendes Präfix für einen
Schlüssel ergeben, können die Werte mit größerer Geschwindigkeit aus dem
Index-Baum abgerufen werden:

@example
SELECT schluessel_teil3 FROM tabelle WHERE schluessel_teil1=1
@end example

@end itemize

Angenommen, Sie führen folgendes @code{SELECT}-Statement aus:

@example
mysql> SELECT * FROM tabelle WHERE spalte1=val1 AND spalte2=val2;
@end example

Wenn es einen mehrspaltigen Index auf @code{spalte1} und @code{spalte2}
gibt, können die entsprechenden Zeilen direkt geholt werden. Wenn es
separate einspaltige Indexe auf @code{spalte1} und @code{spalte2} gibt,
versucht der Optimierer, den restriktivsten Index zu finden, indem er
entscheidet, welcher Index weniger Zeilen finden wird, und diesen Index
dann benutzen, um Zeilen abzurufen.

@cindex Indexe, ganz links stehendes Präfix von
@cindex ganz links stehendes Präfix von Indexen
Wenn die Tabelle einen mehrspaltigen Index hat, kann jedes Präfix auf der
linken Seite vom Optimierer verwendet werden, um Zeilen zu finden. Wenn Sie
zum Beispiel einen dreispaltigen Index auf @code{(spalte1,spalte2,spalte3)}
haben, haben Sie Suchmöglichkeiten auf @code{(spalte1)},
@code{(spalte1,spalte2)} und @code{(spalte1,spalte2,spalte3)} indiziert.

MySQL kann keinen teilweisen Index verwenden, wenn die Spalten kein ganz
linkes Präfix des Indexes bilden. Angenommen, Sie haben folgende
@code{SELECT}-Statements:

@example
mysql> SELECT * FROM tabelle WHERE spalte1=wert1;
mysql> SELECT * FROM tabelle WHERE spalte2=wert2;
mysql> SELECT * FROM tabelle WHERE spalte2=wert2 AND spalte3=wert3;
@end example

Wenn es einen Index auf @code{(spalte1,spalte2,spalte3)} gibt, benutzt nur die
erste der drei Anfragen den Index. Die zweite und dritte Anfrage umfassen
indizierte Spalten, aber @code{(spalte2)} und @code{(spalte2,spalte3)} sind
nicht die ganz linken Präfixe von @code{(spalte1,spalte2,spalte3)}.

@findex LIKE und Indexe
@findex LIKE und Platzhalter
@cindex Indexe und @code{LIKE}
@cindex Platzhalter und @code{LIKE}
MySQL benutzt Indexe auch für @code{LIKE}-Vergleiche, wenn das Argument für
@code{LIKE} eine Zeichenketten-Konstante ist, die nicht mit einem
Platzhalterzeichen anfängt. Die folgenden @code{SELECT}-Statements zum
Beispiel benutzen Indexe:

@example
mysql> select * from tabelle where schluessel_spalte LIKE "Patrick%";
mysql> select * from tabelle where schluessel_spalte LIKE "Pat%_ck%";
@end example

Im ersten Statement werden nur Zeilen mit @code{"Patrick" <=
schluessel_spalte < "Patricl"} berücksichtigt. Im zweiten Statement werden
nur Zeilen mit @code{"Pat" <= schluessel_spalte < "Pau"} berücksichtigt.

Die folgenden @code{SELECT}-Statements benutzen keine Indexe:
@example
mysql> select * from tabelle where schluessel_spalte LIKE "%Patrick%";
mysql> select * from tabelle where schluessel_spalte LIKE andere_spalte;
@end example

Im ersten Statement fängt der @code{LIKE}-Wert mit einem Platzhalterzeichen
an. Im zweiten Statement ist der @code{LIKE}-Wert keine Konstante.

@findex @code{IS NULL} und Indexe
@cindex Indexe und @code{IS NULL}
Suchen mit @code{spalte IS NULL} benutzt Indexe, wenn spalte ein Index ist.

MySQL benutzt normalerweise den Index, der die geringste Anzahl von Zeilen
findet. Ein Index wird benutzt für Spalten, die Sie mit folgenden
Operatoren vergleichen: @code{=}, @code{>}, @code{>=}, @code{<}, @code{<=},
@code{BETWEEN} und einem @code{LIKE} ohne Platzhalter-Präfix wie
@code{'etwas%'}.

Jeder Index, der nicht alle @code{AND}-Ebenen in der @code{WHERE}-Klausel
umfasst, wird nicht benutzt, um die Anfrage zu optimieren. Mit anderen
Worte: Um einen Index benutzen zu können, muss ein Präfix des Indexes in
jeder @code{AND}-Gruppe benutzt werden.

Die folgenden @code{WHERE}-Klauseln benutzen Indexe:
@example
... WHERE index_teil1=1 AND index_teil2=2 AND andere_spalte=3
... WHERE index=1 OR A=10 AND index=2      /* index = 1 OR index = 2 */
... WHERE index_teil1='hello' AND index_teil_3=5
          /* optimiert "index_teil1='hello'" */
... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
          /* kann den Index auf index1 benutzen, aber nicht auf index2 oder index 3 */
@end example

Die folgenden @code{WHERE}-Klauseln benutzen @strong{KEINE} Indexe:
@example
... WHERE index_teil2=1 AND index_teil3=2  /* index_teil_1 wird nicht benutzt */
... WHERE index=1 OR A=10                  /* Index wird nicht in beiden AND-Teilen benutzt */
... WHERE index_teil1=1 OR index_teil2=10  /* Kein Index umfasst alle Zeilen */
@end example

Beachten Sie, dass MySQL in manchen Fällen keinen Index benutzt, selbst
wenn einer verfügbar wäre. Einige solcher Fälle sind hier aufgeführt:

@itemize @bullet
@item
Wenn die Benutzung des Indexes erfordern würde, dass MySQL auf mehr als 30%
der Zeilen in der Tabelle zugreift. (In diesem Fall ist ein Tabellenscan
wahrscheinlich viel schneller, weil dieser weniger Festplattenzugriffe
braucht.) Beachten Sie, dass MySQL den Index dennoch benutzt, wenn eine
Anfrage @code{LIMIT} benutzt, um nur ein paar Zeilen abzufragen, weil er
dann schneller die wenigen Zeilen im Ergebnis finden kann.
@end itemize




@node Indexes, Multiple-column indexes, MySQL indexes, Optimising Database Structure
@c German node Indexe
@subsection Spalten-Indexe

@cindex Indexe, Spalten
@cindex Spalten, Indexe
@cindex Schlüssel

Alle MySQL-Spaltentypen können indiziert werden. Die Benutzung von Indexen
auf den relevanten Spalten ist die beste Art, die Performance von
@code{SELECT}-Operationen zu verbessern.

Die maximale Anzahl von Schlüsseln und die maximale Index-Länge ist durch
den Tabellen-Handler vorgegeben. @xref{Table types}. Bei allen
Tabellen-Handlern können Sie zumindest 16 Schlüssel und eine
Gesamtindexlänge von zumindest 256 Bytes haben.

Bei @code{CHAR}- und @code{VARCHAR}-Spalten können Sie ein Präfix einer
Spalte indexieren. Das ist viel schneller und erfordert weniger
Plattenspeicher als das Indexieren einer ganzen Spalte. Die Syntax, die im
@code{CREATE TABLE}-Statement benutzt wird, um ein Spaltenpräfix zu
indexieren, sieht wie folgt aus:

@example
KEY index_name (spalten_name(laenge))
@end example

Das unten stehende Beispiel erzeugt einen Index auf die ersten 10 Zeichen
der @code{name}-Spalte:

@example
mysql> CREATE TABLE test (
           name CHAR(200) NOT NULL,
           KEY index_name (name(10)));
@end example

Bei @code{BLOB}- und @code{TEXT}-Spalten müssen Sie ein Präfix der Spalte
indexieren. Sie können nicht die gesamte Spalte indexieren.

Ab MySQL-Version 3.23.23 können Sie auch spezielle @strong{FULLTEXT}-Indexe
erzeugen. Sie werden für die Volltextsuche benutzt. Nur der
@code{MyISAM}-Tabellentyp unterstützt @code{FULLTEXT}-Indexe. Sie können
nur auf @code{VARCHAR}- und @code{TEXT}-Spalten erzeugt werden. Die
Indexierung erfolgt immer über die gesamte Spalte; teilweises Indexieren
wird nicht unterstützt. Siehe @ref{Fulltext Search} für Details.

@node Multiple-column indexes, Open tables, Indexes, Optimising Database Structure
@c German node Mehrspaltige Indexe
@subsection Mehrspaltige Indexe

@cindex mehrspaltige Indexe
@cindex Indexe, mehrspaltige
@cindex Schlüssel, mehrspaltige

MySQL kann Indexe auf mehrfache Spalten erzeugen. Ein Index darf aus bis zu
15 Spalten bestehen. (Auf @code{CHAR}- und @code{VARCHAR}-Spalten können
Sie auch ein Präfix der Spalte als Teil eines Indexes benutzen).

Ein mehrspaltiger Index kann als sortiertes Array betrachtet werden, das
Werte enthält, die durch die Verkettung der Werte der indizierten Spalten
erzeugt werden.

MySQL benutzt mehrspaltige Indexe in einer Art, dass Anfragen schnell
werden, wenn Sie eine bekannte Menge für die erste Spalte des Indexes in
einer @code{WHERE}-Klausel angeben, selbst wenn Sie keine Werte für die
anderen Spalten angeben.

Angenommen, einen Tabelle wurde wie folgt erzeugt:

@example
mysql> CREATE TABLE test (
           id INT NOT NULL,
           nachname CHAR(30) NOT NULL,
           vorname CHAR(30) NOT NULL,
           PRIMARY KEY (id),
           INDEX name (nachname,vorname));
@end example

Dann ist der Index @code{name} ein Index über @code{nachname} und
@code{vorname}. Der Index wird für Anfragen benutzt, die Werte in einem
bekannten Bereich für @code{nachname} angeben, oder sowohl für
@code{nachname} als auch für und @code{vorname}.
Daher wird der @code{name}-Index in folgenden Anfragen benutzt:

@example
mysql> SELECT * FROM test WHERE nachname="Widenius";

mysql> SELECT * FROM test WHERE nachname="Widenius"
                          AND vorname="Michael";

mysql> SELECT * FROM test WHERE nachname="Widenius"
                          AND (vorname="Michael" OR vorname="Monty");

mysql> SELECT * FROM test WHERE nachname="Widenius"
                          AND vorname >="M" AND vorname < "N";
@end example

In folgenden Anfragen wird der @code{name}-Index jedoch NICHT benutzt:

@example
mysql> SELECT * FROM test WHERE vorname="Michael";

mysql> SELECT * FROM test WHERE nachname="Widenius"
                          OR vorname="Michael";
@end example

Weitere Informationen über die Art, wie MySQL Indexe benutzt, um die
Anfragen-Performance zu verbessern, finden Sie unter @ref{MySQL indexes, ,
MySQL-Indexe}.


@node Open tables, Table cache, Multiple-column indexes, Optimising Database Structure
@c German node Tabellen-Cache
@subsection Wie MySQL Tabellen öffnet und schließt

@findex table_cache

@cindex Tabellen, öffnen
@cindex Tabellen, schließen
@cindex öffnen, Tabellen
@cindex schließen, Tabellen
@cindex Tabellen-Cache

@code{table_cache}, @code{max_connections} und @code{max_tmp_tables}
beeinflussen die maximale Anzahl von Dateien, die der Server offen halten
kann. Wenn Sie einen oder mehrere dieser Werte erhöhen, können Sie an eine
Begrenzung stoßen, die durch Ihr Betriebssystem in Bezug auf die Anzahl
offener Datei-Deskriptoren pro Prozess festgelegt wird. Diese Begrenzung
kann man jedoch auf vielen Systemen erhöhen. Sehen Sie im Handbuch Ihres
Betriebssystems nach, wie man das macht, weil die Methode, wie die
Begrenzung geändert wird, sich von System zu System stark unterscheidet.

@code{table_cache} ist verwandt mit @code{max_connections}. Für 200
gleichzeitig laufende Verbindungen sollten Sie zum Beispiel einen
Tabellen-Cache von mindestens @code{200 * n} haben, wobei @code{n} die
maximale Anzahl von Tabellen in einem Join ist. Zusätzlich müssen Sie
einige externe Datei-Deskriptoren für temporäre Tabellen und Dateien
reservieren.

Stellen Sie sicher, dass Ihr Betriebssystem die Anzahl offener
Datei-Deskriptoren handhaben kann, die durch die
@code{table_cache}-Einstellung impliziert wird. Wenn
@code{table_cache} zu hoch gesetzt wird, hat MySQL eventuell keine
Datei-Deskriptoren mehr und verweigert Verbindungen, führt keine Anfragen
mehr aus und läuft sehr unzuverlässig. Beachten Sie auch, dass der
MyISAM-Tabellen-Handler zwei Datei-Deskriptoren für jede einzelne offene
Tabelle benötigt. Sie können die Anzahl von Datei-Deskriptoren, die für
MySQL verfügbar sind, in der @code{--open-files-limit=#}-Startoption
angeben. @xref{Not enough file handles}.

Der Cache offener Tabellen kann bis auf @code{table_cache} anwachsen
(Vorgabewert 64; das kann mit der @code{-O Tabellen-Cache=#}-Option für
@code{mysqld} geändert werden). Eine Tabelle wird nie geschlossen, ausser
wen der Cache voll ist und ein anderer Thread versucht, eine Tabelle zu
öffnen, oder wenn Sie @code{mysqladmin refresh} oder @code{mysqladmin
flush-tables} benutzen.

Wenn sich der Tabellen-Cache füllt, benutzt der Server folgenden Prozedur,
um einen Cache-Eintrag für die Benutzung zu finden:

@itemize @bullet
@item
Tabellen, die momentan nicht in Benutzung sind, werden freigegeben, in der
Reihenfolge der kürzlich am wenigsten benutzten Tabellen.

@item
Wenn der Cache voll ist und keine Tabellen freigegeben werden können, aber
eine neue Tabelle geöffnet werden muss, wird der Cache temporär wie
benötigt vergrößert.

@item
Wenn der Cache gerade im Zustand temporärer Erweiterung ist und eine
Tabelle vom Zustand benutzt in den Zustand nicht benutzt wechselt, wird die
Tabelle geschlossen und vom Cache freigesetzt.
@end itemize

Eine Tabelle wird für jeden gleichzeitigen Zugriff geöffnet. Das bedeutet,
dass die Tabelle zweimal geöffnet werden muss, wenn Sie zwei Threads haben,
die auf dieselbe Tabelle zugreifen oder einen Thread, der auf die Tabelle
zweimal in derselben Anfrage zugreift (mit @code{AS}). Das erste öffnen
jeder Tabelle benötigt nur einen Datei-Deskriptor. Der zusätzliche
Deskriptor wird für die Index-Datei benötigt; dieser Deskriptor wird
mit allen Threads geteilt (shared).

Wenn Sie eine Tabelle mit dem @code{HANDLER tabelle OPEN}-Statement öffnen,
wird dem Thread ein dediziertes Tabellenobjekt zugewiesen. Diese
Tabellenobjekt wird nicht mit anderen Threads geteilt und wird solange
nicht geschlossen, bis der Thread @code{HANDLER tabelle CLOSE} aufruft oder
stirbt.
@xref{INSERT}.

Sie können prüfen, ob Ihr Tabellen-Cache zu klein ist, indem Sie die
mysqld-Variable @code{opened_tables} ansehen. Wenn diese recht Groß ist,
selbst wenn Sie nicht viele @code{FLUSH TABLES} ausgeführt haben, sollten
Sie Ihren Tabellen-Cache vergrößern. @xref{SHOW STATUS}.


@node Table cache, Creating many tables, Open tables, Optimising Database Structure
@c German node Viele Tabellen erzeugen
@subsection Nachteile der Erzeugung großer Mengen von Tabellen in derselben Datenbank

@cindex Tabellen, zu viele

Wenn Sie viele Dateien in einem Verzeichnis haben, werden open-, close- und
create-Operationen langsam. Wenn Sie ein @code{SELECT}-Statements auf viele
unterschiedliche Tabellen ausführen, gibt es ein bisschen Overhead, wenn
der Tabellen-Cache voll ist, weil für jede Tabelle, die geöffnet wird, eine
andere geschlossen werden muss. Sie können diese Overhead verringern, indem
Sie den Tabellen-Cache größer machen.


@node Creating many tables,  , Table cache, Optimising Database Structure
@c German node Offene Tabellen
@subsection Warum gibt es so viele offene Tabellen?

@cindex Tabellen, offene
@cindex offene Tabellen

Wenn Sie @code{mysqladmin status} ausführen, werden Sie etwa folgendes
sehen:

@example
Uptime: 426 Running Threads: 1 Questions: 11082 Reloads: 1 Open Tables: 12
@end example

Das kann etwas verwirrend sein, wenn Sie nur 6 Tabellen haben.

MySQL ist multi-threaded, daher kann er viele Anfragen auf dieselbe Tabelle
simultan verarbeiten. Um das Problem zu minimieren, dass zwei Threads
verschiedene Zustände in Bezug auf dieselbe Datei haben, wird die Tabelle
unabhängig für jeden gleichzeitigen Thread geöffnet. Das benötigt etwas
Arbeitsspeicher und einen externen Datei-Deskriptor für die Daten-Datei.
Der Index-Datei-Deskriptor wird mit allen Threads geteilt.


@node Optimising the Server, Disk issues, Optimising Database Structure, MySQL Optimisation
@c German node Optimierung des Servers
@section Optimierung des MySQL-Servers




@menu
* System::                      
* Server parameters::           
* Compile and link options::    
* Memory use::                  
* DNS::                         
* SET OPTION::                  
@end menu

@node System, Server parameters, Optimising the Server, Optimising the Server
@c German node System
@subsection System / Kompilierzeitpunkt und Tuning der Startparameter

@cindex Kompilieren, Optimierung
@cindex System-Optimierung
@cindex Startparameter, tunen

Wir fangen mit den Dingen auf Systemebene an, weil einige dieser
Entscheidungen sehr früh getroffen werden müssen. In anderen Fällen mag ein
kurzer Blick auf diesen Teil ausreichen, weil er nicht so wichtig für
große Verbesserungen ist. Es ist jedoch immer nett, ein Gefühl dafür zu
bekommen, wie viel man gewinnen kann, wenn man Dinge auf dieser Ebene
ändert.

Es ist wirklich wichtig, dass vorgabemäßige Betriebssystem zu kennen! Um
das meiste aus Mehrprozessor-Maschinen herauszuholen, sollte man Solaris
benutzen (weil die Threads wirklich gut funktionieren) oder Linux (weil der
2.2-Kernel wirklich gute Mehrprozessor-Unterstützung bietet). Linux hat auf
32-Bit-Maschinen vorgabemäßig eine Dateigrößenbeschränkung von 2 GB. Das
wird hoffentlich bald behoben, wenn neue Dateisysteme herausgebracht werden
(XFS/Reiserfs). Wenn Sie dringen Unterstützung für größere Datei als 2 GB
auf Linux-Intel-32-Bit benötigen, sollten Sie den LFS-Patch für das
ext2-Dateisystem holen.

Weil wir MySQL noch nicht auf allzu vielen Plattformen in einer
Produktionsumgebung getestet haben, empfehlen wir, dass Sie Ihre geplante
Plattform testen, bevor Sie sich dafür entscheiden.

@cindex Sperren
Weitere Tipps:
@itemize @bullet
@item
Wenn Sie genug Arbeitsspeicher haben, könnten Sie alle Swap-Geräte
entfernen. Einige Betriebssysteme benutzen in bestimmten Zusammenhängen ein
Swap-Gerät, selbst wenn Sie freien Arbeitsspeicher haben.
@item
Benutzen Sie die @code{--skip-locking}-MySQL-Option, um externe Sperren zu
vermeiden. Beachten Sie, dass das die Funktionalität von MySQL nicht
tangiert, solange Sie nur einen Server laufen lassen. Denken Sie lediglich
daran, den Server herunterzufahren (oder die relevanten Teile zu sperren),
bevor Sie @code{myisamchk} laufen lassen. Auf manchen Systemen ist diese
Umschaltung zwingend erforderlich, weil externes Sperren in keinem Fall
funktioniert.

Die @code{--skip-locking}-Option ist vorgabemäßig angeschaltet, wenn Sie
mit MIT-pThreads kompilieren, weil @code{flock()} von MIT-pThreads nicht
vollständig auf allen Plattformen unterstützt wird. Auch für Linux ist es
vorgabemäßig angeschaltet, weil Linux-Dateisperren bis jetzt nicht
zuverlässig funktionieren.

Der einzige Fall, wo Sie @code{--skip-locking} nicht benutzen können, sit,
wenn Sie mehrfache MySQL-@emph{Server} (nicht Clients) auf denselben Daten
laufen lassen, oder wenn Sie @code{myisamchk} auf eine Tabelle ausführen,
ohne zuerst die @code{mysqld}-Server-Tabellen auf Platte zurückzuschreiben
und zu sperren.

Sie können immer noch @code{LOCK TABLES} / @code{UNLOCK TABLES} benutzen,
selbst wenn Sie @code{--skip-locking} benutzen.
@end itemize


@node Server parameters, Compile and link options, System, Optimising the Server
@c German node Serverparameter
@subsection Serverparameter tunen

@cindex Parameter, Server
@cindex @code{mysqld}-Server, Puffer-Größen
@cindex Puffer-Größen, @code{mysqld}-Server
@cindex Startparameter

Sie erhalten die Puffer-Größen, die der @code{mysqld}-Server benutzt, mit
diesem Befehl:

@example
shell> mysqld --help
@end example

@cindex @code{mysqld}-Optionen
@cindex Variablen, @code{mysqld}
Dieser Befehl erzeugt eine Auflistung aller @code{mysqld}-Optionen und
konfigurierbaren Variablen. Die Ausgabe enthält die Vorgabewerte und sieht
etwa wie folgt aus:

@example
Possible variables for option --set-variable (-O) are:
back_log              current value: 5
bdb_cache_size        current value: 1048540
binlog_cache_size     current_value: 32768
connect_timeout       current value: 5
delayed_insert_timeout  current value: 300
delayed_insert_limit  current value: 100
delayed_queue_size    current value: 1000
flush_time            current value: 0
interactive_timeout   current value: 28800
join_buffer_size      current value: 131072
key_buffer_size       current value: 1048540
lower_case_tabelles  current value: 0
long_query_time       current value: 10
max_allowed_packet    current value: 1048576
max_binlog_cache_size current_value: 4294967295
max_connections       current value: 100
max_connect_errors    current value: 10
max_delayed_threads   current value: 20
max_heap_table_size   current value: 16777216
max_join_size         current value: 4294967295
max_sort_length       current value: 1024
max_tmp_tables        current value: 32
max_write_lock_count  current value: 4294967295
myisam_sort_buffer_size  current value: 8388608
net_buffer_length     current value: 16384
net_retry_count       current value: 10
net_read_timeout      current value: 30
net_write_timeout     current value: 60
query_buffer_size     current value: 0
record_buffer         current value: 131072
record_rnd_buffer     current value: 131072
slow_launch_time      current value: 2
sort_buffer           current value: 2097116
table_cache           current value: 64
thread_concurrency    current value: 10
tmp_table_size        current value: 1048576
thread_stack          current value: 131072
wait_timeout          current value: 28800
@end example

Wenn aktuell ein @code{mysqld}-Server läuft, können Sie feststellen, welche
Werte er für die Variablen tatsächlich benutzt, wenn Sie diesen Befehl
ausführen:

@example
shell> mysqladmin variables
@end example

Sie finden eine komplette Beschreibung aller Variablen im @code{SHOW
VARIABLES}-Abschnitt dieses Handbuchs. @xref{SHOW VARIABLES}.

Wenn Sie @code{SHOW STATUS} eingeben, können Sie einige statistische
Informationen des Servers sehen. @xref{SHOW STATUS}.

MySQL benutzt Algorithmen, die sehr skalierbar sind, daher können Sie
üblicherweise mit sehr wenig Arbeitsspeicher fahren. Wenn Sie MySQL jedoch
mehr Speicher geben, erzielen Sie damit normalerweise auch bessere
Performance.

Wenn Sie einen MySQL-Server tunen, sind die zwei wichtigsten Variablen
@code{key_buffer_size} und @code{table_cache}. Sie sollten zunächst sicher
sein, dass diese beiden richtig gesetzt sind, bevor Sie versuchen, irgend
eine der anderen Variablen zu ändern.

Wenn Sie viel Arbeitsspeicher haben (>= 256 MB) und viele Tabellen und
maximale Performance bei einer mäßigen Anzahl von Clients haben wollen,
sollten Sie etwas wie das Folgende benutzen:

@example
shell> safe_mysqld -O key_buffer=64M -O table_cache=256 \
           -O sort_buffer=4M -O record_buffer=1M &
@end example

Wenn Sie nur 128 MB und nur wenige Tabellen haben, aber viele
Sortiervorgänge durchführen, können Sie etwas wie das Folgende benutzen:

@example
shell> safe_mysqld -O key_buffer=16M -O sort_buffer=1M
@end example

Wenn Sie wenig Arbeitsspeicher und viele Verbindungen haben, können Sie
etwas wie das Folgende benutzen:

@example
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=100k \
           -O record_buffer=100k &
@end example

Oder sogar:

@example
shell> safe_mysqld -O key_buffer=512k -O sort_buffer=16k \
           -O table_cache=32 -O record_buffer=8k -O net_buffer=1K &
@end example

Wenn Sie @code{GROUP BY} oder @code{ORDER BY} auf Dateien anwenden, die
größer als Ihr verfügbarer Arbeitsspeicher sind, sollten Sie den Wert von
@code{record_rnd_buffer} heraufsetzen, um das Lesen von Zeilen nach
Sortiervorgängen zu beschleunigen.

Wenn Sie MySQL installiert haben, enthält das
@file{Support-files}-Verzeichnis einige unterschiedliche
@code{my.cnf}-Beispiel-Dateien: @file{my-huge.cnf}, @file{my-large.cnf},
@file{my-medium.cnf} und @file{my-small.cnf}. Diese können Sie als
Grundlage nehmen, um Ihr System zu optimieren.

Wenn es sehr viele Verbindungen gibt, können ``Swapping-Probleme''
auftauchen, wen Sie @code{mysqld} nicht so konfiguriert haben, dass er für
jede Verbindung sehr wenig Speicher benutzt. @code{mysqld} bringt natürlich
bessere Leistungsdaten, wenn Sie genug Speicher für alle Verbindungen
haben.

Beachten Sie, dass Änderungen einer Option für @code{mysqld} sich nur auf
diese Instanz des Servers auswirken.

Um die Auswirkung einer Parameteränderung zu sehen, geben Sie folgendes
ein:

@example
shell> mysqld -O key_buffer=32m --help
@end example

Stellen Sie sicher, dass die @code{--help}-Option zuletzt kommt, ansonsten
wird die Auswirkung jeglicher Optionen, die danach auf der Kommandozeile
kommen, in der Ausgabe nicht gezeigt.
output.


@node Compile and link options, Memory use, Server parameters, Optimising the Server
@c German node Kompilier- und Link-Optionen
@subsection Wie Kompilieren und Linken die Geschwindigkeit von MySQL beeinflusst

@cindex Linken, Geschwindigkeit
@cindex Kompilieren, Geschwindigkeit
@cindex Geschwindigkeit, Kompilieren
@cindex Geschwindigkeit, Linken

Die meisten der folgenden Tests wurden mit den MySQL-Benchmarks unter Linux
durchgeführt, aber sie sollten einen guten Anhaltspunkt für andere
Betriebssysteme und Auslastungen geben.

Sie erhalten die schnellste ausführbare Datei, wenn Sie mit @code{-static}
linken.

Unter Linux erhalten Sie den schnellsten Code, wenn Sie mit @code{pgcc} und
@code{-O3} kompilieren. Um @file{sql_yacc.cc} mit diesen Optionen zu
kompilieren, brauchen Sie etwa 200 MB Arbeitsspeicher, weil @code{gcc/pgcc}
viel Speicher benötigt, um alle Funktionen inline zu machen. Sie sollten
beim Konfigurieren von MySQL auch @code{CXX=gcc} setzen, um das
Einschließen der @code{libstdc++}-Bibliothek zu vermeiden (die nicht
benötigt wird). Beachten Sie, dass bei einigen Version von @code{pgcc} der
erzeugte Code nur auf echten Pentium-Prozessoren läuft, selbst wenn Sie in
den Compiler-Optionen angeben, dass Sie wollen, dass der Code auf alle
Prozessoren vom Typ x586 läuft (wie AMD).

Einfach durch die Benutzung eines besseren Compilers und / oder besserer
Compiler-Optionen können Sie eine 10-30%-ige Geschwindigkeitssteigerung in
Ihrer Applikation erhalten. Das ist besonders wichtig, wenn Sie den
SQL-Server selbst kompilieren!

Wir haben sowohl Cygnus CodeFusion als auch Fujitsu-Compiler getestet, aber
es stellte sich heraus, dass keiner von beiden ausreichend Bug-frei war,
damit MySQL mit angeschalteten Optimierungen kompiliert werden konnte.

Wenn Sie MySQL kompilieren, sollten Sie nur Unterstützung für die
Zeichensätze einschließen, die Sie benutzen werden (Option
@code{--with-charset=xxx}). Die Standard-MySQL-Binärdistributionen werden
mit Unterstützung für alle Zeichensätze kompiliert.

Hier ist eine Auflistung einiger Messungen, die wir durchgeführt haben:
@itemize @bullet
@item
Wenn Sie @code{pgcc} benutzen und alles mit @code{-O6} kompilieren, ist der
@code{mysqld}-Server 1% schneller als mit @code{gcc} 2.95.2.

@item
Wenn Sie dynamisch linken (ohne @code{-static}), ist das Ergebnis unter
Linux 13% langsamer. Beachten Sie, dass Sie dennoch dynamisch gelinkte
MySQL-Bibliotheken benutzen können. Nur beim Server ist das kritisch in
Bezug auf Performance.

@item
Wenn Sie Ihre @code{mysqld}-Binärdatei mit @code{strip libexec/mysqld}
strippen, ist die resultierende Binärdatei bis zu 4% schneller.

@item
Wenn Sie sich über TCP/IP statt über Unix-Sockets verbinden, ist das auf
demselben Computer 7,5% langsamer. (Wenn Sie sich zu @code{localhost}
verbinden, benutzt MySQL vorgabemäßig Sockets.)

@item
Wenn Sie sich über TCP/IP von einem anderen Computer über ein
100-MBit-Ethernet verbinden, ist das 8% bis 11% langsamer.

@item
Wenn Sie mit @code{--with-debug=full} kompilieren, verlangsamen sich die
meisten Anfragen um 20%, manche Anfragen jedoch werden wesentlich langsamer
(der MySQL-Benchmarks zeigte 35%). Wenn Sie @code{--with-debug} benutzen,
beträgt die Verlangsamung nur 15%. Wenn Sie eine @code{mysqld}-Version, die
mit @code{--with-debug=full} kompiliert wurde, mit @code{--skip-safemalloc}
starten, ist die Geschwindigkeit etwa dasselbe, als wenn Sie mit
@code{--with-debug} konfigurieren.

@item
Auf einer Sun SPARCstation 20 ist SunPro C++ 4.2 5% schneller als
@code{gcc} 2.95.2.

@item
Das Kompilieren mit @code{gcc} 2.95.2 für ultrasparc mit der Option
@code{-mcpu=v8 -Wa,-xarch=v8plusa} ergibt 4% mehr Performance.

@item
Auf Solaris 2.5.1 sind MIT-pThreads 8% bis 12% langsamer als Solaris-native
Threads, auf einem Einprozessorsystem. Bei mehr Last / Prozessoren sollte
der Unterschied größer werden.

@item
Laufenlassen mit @code{--log-bin} macht @strong{MySQL} 1% langsamer.

@item
Wenn beim Kompilieren unter Linux-x86 mit gcc keine Frame-Pointers
@code{-fomit-frame-pointer} oder @code{-fomit-frame-pointer -ffixed-ebp}
verwendet werden, ist @code{mysqld} 1% bis 4% schneller.
@end itemize

Die MySQL-Linux-Distribution, die von MySQL AB zur Verfügung gestellt wird,
wurde früher mit @code{pgcc} kompiliert, aber wir mussten zum normalen gcc
zurück gehen, weil es einen Bug in @code{pgcc} gibt, der Code erzeugt, der
nicht auf AMD läuft. Wir werden gcc solange benutzen, bis dieser Bug
behoben ist. Bis dahin können Sie, falls Sie keine AMD-Maschine haben, eine
schnellere Binärdatei erhalten, wenn Sie mit @code{pgcc} kompilieren. Die
Standard-MySQL-Linux-Binärdatei wird statisch gelinkt, um sie schneller und
portierbarer zu machen.


@node Memory use, DNS, Compile and link options, Optimising the Server
@c German node Speicherbenutzung
@subsection Wie MySQL Speicher benutzt

@cindex Speicherbenutzung

Die unten stehende Liste zeigt einige Möglichkeiten, wie der
@code{mysqld}-Server Speicher benutzt. Wo es zutrifft, wird der Name der
für die Speicherbenutzung relevanten Servervariablen angegeben.

@itemize @bullet
@item
Der Schlüssel-Puffer (Variable @code{key_buffer_size}) wird von allen
Threads geteilt. Andere Puffer, die vom Server benutzt werden, werden bei
Bedarf zugewiesen. @xref{Server parameters}.

@item
Jede Verbindung benutzt etwas Thread-spezifischen Platz: Einen Stack
(Vorgabe 64 KB, Variable @code{thread_stack}), einen Verbindungspuffer
(Variable @code{net_buffer_length}) und a Ergebnispuffer (Variable
@code{net_buffer_length}). Die Verbindungspuffer und Ergebnispuffer werden
bei Bedarf dynamisch bis zu @code{max_allowed_packet} vergrößert. Wenn
eine Anfrage läuft, wird auch eine Kopie der aktuellen Anfragezeichenkette
zugewiesen.

@item
Alle Threads teilen sich denselben grundlegenden Speicher.

@item
Nur die komprimierten ISAM- / MyISAM-Tabellen werden Speicher-gemappt. Das
liegt daran, dass der 32-Bit-Adressraum von 4 GB für die meisten großen
Tabellen nicht Groß genug ist. Wenn Systeme mit 64-Bit-Adressraum
gebräuchlicher werden, werden wir vielleicht eine allgemeine Unterstützung
für Speicher-Mapping hinzufügen.

@item
Jeder Anfrage, die einen sequentiellen Scan über eine Tabelle durchführt,
wird ein Lesepuffer zugewiesen (Variable @code{record_buffer}).

@item
Wenn Zeilen in 'zufälliger' Reihenfolge gelesen werden (zum Beispiel nach
einem Sortiervorgang), wird ein Zufalls-Lesepuffer zugewiesen, um
Suchvorgänge auf Festplatte zu vermeiden. (Variable @code{record_rnd_buffer}).

@item
Alle Joins werden in einem Durchgang durchgeführt und die meisten Joins
können sogar ohne Benutzung einer temporären Tabelle durchgeführt werden.
Die meisten temporären Tabellen sind Speicher-basierende (HEAP-) Tabellen.
Temporäre Tabellen mit großer Datensatzlänge (berechnet als Summe aller
Spaltenlängen) oder die @code{BLOB}-Spalten enthalten, werden auf
Festplatte gespeichert.

Ein Problem in MySQL-Versionen vor Version 3.23.2 ist, dass Sie den Fehler 
@code{The table tabelle is full} erhalten, wenn die Größe der HEAP-Tabelle
@code{tmp_table_size} überschreitet. In neueren Versionen wird dies so
gehandhabt, dass die Speicher-basierende (HEAP-) Tabelle bei Bedarf
automatisch in eine Festplatten-basierende Tabelle (MyISAM) umgewandelt
wird. Um das Problem zu umgehen, können Sie die Größe von temporären
Tabellen durch Setzen der @code{tmp_table_size}-Option für @code{mysqld}
ändern, oder durch Setzen der SQL-Option @code{SQL_BIG_TABLES} im
Client-Programm.  @xref{SET OPTION, , @code{SET OPTION}}. In MySQL-Version
3.20 war die maximale Größe der temporären Tabelle
@code{record_buffer*16}. Wenn Sie also diese Version benutzen, müssen Sie
den Wert von @code{record_buffer} herauf setzen. Sie können @code{mysqld}
auch mit der @code{--big-tables}-Option starten, um temporäre Tabellen
immer auf Festplatte zu speichern. Das wird jedoch die Geschwindigkeit
vieler komplizierter Anfragen beeinflussen.

@item
Den meisten Sortier-Anfragen werden ein Sortierpuffer und 0 bis 2 temporäre
Dateien zugewiesen, abhängig von der Größe der Ergebnismenge.
@xref{Temporary files}.

@item
Fast alles Parsen und Berechnen wird in einem lokalen Speicherbereich
durchgeführt. Für kleine Sachen wird kein Speicher-Overhead benötigt, und
das normale, langsame Zuweisen und Freimachen von Speicher wird vermieden.
Speicher wird nur für unerwartet lange Zeichenketten zugewiesen (das wird
mit @code{malloc()} und @code{free()} gemacht).

@item
Jede Index-Datei wird einmal geöffnet. Die Daten-Datei wird einmal für
jeden gleichzeitig laufenden Thread geöffnet. Für jeden gleichzeitigen
Thread wird eine Tabellenstruktur, Spaltenstrukturen für jede Spalte und
ein Puffer der Größe @code{3 * n} zugewiesen, wobei @code{n} die maximale
Zeilenlänge ist (@code{BLOB}-Spalten werden nicht mitgerechnet). Eine
@code{BLOB}-Spalte benutzt 5 bis 8 Bytes plus die Länge der
@code{BLOB}-Daten. Der @code{ISAM}- / @code{MyISAM}-Tabellen-Handler
benutzt einen zusätzlichen Zeilenpuffer für internen Gebrauch.

@item
Bei jeder Tabelle, die @code{BLOB}-Spalten enthält, wird ein Puffer
dynamisch vergrößert, um größere @code{BLOB}-Werte einzulesen. Wenn Sie
eine Tabelle scannen, wird ein Puffer so Groß wie der größte
@code{BLOB}-Wert zugewiesen.

@item
Tabellen-Handler für alle Tabellen in Benutzung werden in einem Cache
gespeichert und als FIFO verwaltet. Normalerweise hat der Cache 64
Einträge. Wenn eine Tabelle gleichzeitig von zwei laufenden Threads
benutzt wurde, enthält der Cache zwei Einträge für die Tabelle.
@xref{Open tables}.

@item
Ein @code{mysqladmin flush-tables}-Befehl schließt alle Tabellen, die
nicht in Benutzung sind, und kennzeichnet alle Tabellen in Benutzung als zu
schließen, sobald der aktuell ausführende Thread fertig ist. Das setzt
effektiv den meisten benutzten Speicher frei.
@end itemize

@code{ps} und andere System-Status-Programme berichten vielleicht, dass
@code{mysqld} viel Arbeitsspeicher benutzt. Das kann durch Thread-Stacks
auf verschiedenen Speicheradressen verursacht werden. @code{ps} der
Solaris-Version zum Beispiel zählt den unbenutzten Speicher zwischen Stacks
zum benutzten Speicher hinzu. Das können Sie bestätigen, wenn Sie den
verfügbaren Swap mit @code{swap -s} überprüfen. Wir haben @code{mysqld} mit
kommerziellen Memory-Leak-Detektoren getestet, daher sollte es keine
Memory-Leaks geben.


@node DNS, SET OPTION, Memory use, Optimising the Server
@c German node DNS
@subsection Wie MySQL DNS benutzt

@cindex DNS
@cindex Caching von Hostnamen

Wenn sich ein neuer Thread mit @code{mysqld} verbindet, erzeugt
@code{mysqld} einen neuen Thread, um die Anfrage zu handhaben. Dieser
Thread prüft zuerst, ob der Hostname im Hostnamen-Cache ist. Falls nicht,
ruft der Thread @code{gethostbyaddr_r()} und @code{gethostbyname_r()} auf,
um den Hostname aufzulösen.

Wenn das Betriebssystem die oben genannten Thread-sicheren Aufrufe nicht
unterstützt, sperrt der Thread ein Mutex und ruft statt dessen
@code{gethostbyaddr()} und @code{gethostbyname()} auf. Beachten Sie, dass
in diesem Fall kein anderer Thread andere Hostnamen auflösen kann, die
nicht im Hostnamen-Cache sind, bis der erste Thread fertig ist.

Sie können das DNS-Nachschlagen von Hostnamen (DNS-Lookup) abschalten,
indem Sie @code{mysqld} mit @code{--skip-name-resolve} starten. In diesem
Fall können Sie jedoch in den MySQL-Berechtigungstabellen nur IP-Nummern
verwenden.

Wenn Sie ein sehr langsames DNS und viele Hosts haben, können Sie mehr
Performance erzielen, wenn Sie entweder das DNS-Nachschlagen von Hostnamen
(DNS-Lookup) abschalten (mit @code{--skip-name-resolve}) oder
@code{HOST_CACHE_SIZE} (Vorgabe: 128) erhöhen und @code{mysqld}
neu kompilieren.

Sie können den Hostnamen-Cache mit @code{--skip-host-cache} abschalten. Sie
können den Hostnamen-Cache mit @code{FLUSH HOSTS} oder @code{mysqladmin
flush-hosts} löschen.

Wenn Sie keine Verbindungen über @code{TCP/IP} zulassen wollen, starten Sie
@code{mysqld} mit @code{--skip-networking}.


@node SET OPTION,  , DNS, Optimising the Server
@c German node SET OPTION
@subsection @code{SET}-Syntax

@findex SET OPTION

@example
SET [OPTION] SQL_VALUE_OPTION= wert, ...
@end example

@code{SET OPTION} setzt verschiedene Optionen, die die Arbeitsweise des
Servers oder Ihrer Clients beeinflussen. Jede Option, die Sie setzen,
bleibt in Kraft, bis die aktuelle Sitzung beendet wird, oder bis Sie die
Option auf einen anderen Wert setzen.

@table @code
@item characterset zeichensatz_name | DEFAULT
Das mappt alle Zeichenketten von und zum Client auf das angegebene Mapping.
Momentan ist die einzige Option für @code{zeichensatz_name}
@code{cp1251_koi8}, aber Sie können leicht neue Mappings hinzufügen, indem
Sie die @file{sql/convert.cc}-Datei in der MySQL-Quelldistribution
editieren. Das vorgabemäßige Mapping kann durch Setzen des
@code{zeichensatz_name}-Werts auf @code{DEFAULT} wieder hergestellt
werden.

Beachten Sie, dass sich die Syntax für das Setzen der
@code{characterset}-Option von der Syntax für das Setzen anderer Optionen
unterscheidet.

@item PASSWORD = PASSWORD('ein_passwort')
@cindex Passwörter, setzen
Setzt das Passwort für den aktuellen Benutzer. Jeder nicht anonyme Benutzer
kann sein eigenes Passwort ändern!

@item PASSWORD FOR benutzer = PASSWORD('ein_passwort')
Setzt das Passwort für einen bestimmten Benutzer auf dem aktuellen
Server-Host. Das kann nur ein Benutzer mit Zugriff auf die
@code{mysql}-Datenbank tun. Der Benutzer sollte im
@code{user@@hostname}-Format eingegeben werden, wobei @code{user} und
@code{hostname} exakt so sind, wie sie in den @code{User}- und
@code{Host}-Spalten des @code{mysql.user}-Tabelleneintrags aufgelistet
sind. Wenn Sie zum Beispiel in den Spalten @code{User} und @code{Host} die
Einträge @code{'bob'} und @code{'%.loc.gov'} haben wollen, schreiben Sie:

@example
mysql> SET PASSWORD FOR bob@@"%.loc.gov" = PASSWORD("newpass");

oder

mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' und host="%.loc.gov";
@end example

@item SQL_AUTO_IS_NULL = 0 | 1
Falls auf @code{1} gesetzt (Vorgabe), wird mit folgendem Konstrukt die
letzte eingefügte Zeile einer Tabelle mit einer auto_increment-Zeile
gefunden:
@code{WHERE auto_increment_spalte IS NULL}. Das wird von einigen
ODBC-Programme wie Access benutzt.

@item AUTOCOMMIT= 0 | 1
Falls auf @code{1} gesetzt, werden alle Änderungen einer Tabelle auf einmal
durchgeführt. Um eine Transaktion aus mehreren Befehlen anzufangen, müssen
Sie das @code{BEGIN}-Statement benutzen. @xref{COMMIT}. Falls auf @code{0}
gesetzt, müssen Sie @code{COMMIT} / @code{ROLLBACK} benutzen, um diese
Transaktion zu akzeptieren / zu widerrufen. @xref{COMMIT}. Beachten Sie,
dass MySQL nach dem Umschalten vom @code{AUTOCOMMIT}-Modus zum
@code{AUTOCOMMIT}-Modus ein automatisches @code{COMMIT} auf alle offenen
Transaktionen durchführt.

@item SQL_BIG_TABLES = 0 | 1
@cindex table is full
Falls auf @code{1} gesetzt, werden alle temporären Tabellen auf Platte
statt im Arbeitsspeicher gespeichert. Das ist etwas langsamer, aber Sie
erhalten nicht den Fehler @code{The table tabelle is full}, wenn Sie große
@code{SELECT}-Operationen ausführen, die eine große temporäre Tabelle
erfordern. Der Vorgabewert für eine neue Verbindung ist @code{0} (das
heißt, temporäre Tabellen im Arbeitsspeicher benutzen).

@item SQL_BIG_SELECTS = 0 | 1
Falls auf @code{0} gesetzt, bricht MySQL ab, wenn ein @code{SELECT} versucht
wird, das wahrscheinlich sehr lange dauern wird. Das ist nützlich, wenn ein
unratsames @code{WHERE}-Statement abgesetzt wurde. Ein große Anfrage ist
definiert als ein @code{SELECT}, das wahrscheinlich mehr als
@code{max_join_size} Zeilen untersuchen muss. Der Vorgabewert für eine neue
Verbindung ist @code{1} (was alle @code{SELECT}-Statements zuläßt).

@item SQL_BUFFER_RESULT = 0 | 1
@code{SQL_BUFFER_RESULT} erzwingt, dass das Ergebnis von @code{SELECT}'s in
eine temporäre Tabelle geschrieben wird. Das hilft MySQL, die
Tabellensperren frühzeitig aufzuheben, und ist hilfreich in Fällen, wo es
lange dauert, das Ergebnis an den Client zu senden.

@item SQL_LOW_PRIORITY_UPDATES = 0 | 1
Falls auf @code{1} gesetzt, warten alle @code{INSERT}-, @code{UPDATE}-,
@code{DELETE}- und @code{LOCK TABLE WRITE}-Statements, bis es kein
anhängiges @code{SELECT} oder @code{LOCK TABLE READ} für die betroffene
Tabelle gibt.

@item SQL_MAX_JOIN_SIZE = wert | DEFAULT
Nicht zulassen, dass @code{SELECT}s, die wahrscheinlich mehr als
@code{value} Zeilenkombinationen untersuchen müssen, ausgeführt werden.
Wenn Sie diesen Wert setzen, können Sie @code{SELECT}s abfangen, bei denen
Schlüssel nicht korrekt verwendet werden und die wahrscheinlich sehr lange
dauern. Wenn dieser Wert auf etwas anderes als @code{DEFAULT} gesetzt wird,
wird der @code{SQL_BIG_SELECTS}-Flag zurückgesetzt. Wenn Sie den
@code{SQL_BIG_SELECTS}-Flag wieder setzen, wird die
@code{SQL_MAX_JOIN_SIZE}-Variable ignoriert. Sie können für diese Variable
einen Vorgabewert setzen, wenn Sie @code{mysqld} mit @code{-O
max_join_size=#} starten.

@item SQL_SAFE_UPDATES = 0 | 1
Falls auf @code{1} gesetzt, bricht MySQL ab, wenn ein @code{UPDATE} oder
@code{DELETE} versucht wird, das keinen Schlüssel oder kein @code{LIMIT} in
der @code{WHERE}-Klausel benutzt. Das ermöglicht das Abfangen falscher
Aktualisierungen, wenn SQL-Befehle von Hand eingegeben werden.

@item SQL_SELECT_LIMIT = wert | DEFAULT
Die maximale Anzahl von Datensätzen, die von @code{SELECT}-Statements
zurückgegeben werden. Wenn ein @code{SELECT} eine @code{LIMIT}-Klausel hat,
hat das @code{LIMIT} Vorrang vor dem Wert von @code{SQL_SELECT_LIMIT}. Der
Vorgabewert für eine neue Verbindung ist ``unbegrenzt.'' Wenn Sie diese
Begrenzung geändert haben, kann der Vorgabewert wieder hergestellt werden,
indem Sie einen @code{SQL_SELECT_LIMIT}-Wert von @code{DEFAULT} verwenden.

@item SQL_LOG_OFF = 0 | 1
Falls auf @code{1} gesetzt, wird für diesen Client kein Loggen ins
Standard-Log durchgeführt, wenn der Client die
@strong{process}-Berechtigung hat. Das betrifft nicht die
Update-Log-Datei!

@item SQL_LOG_UPDATE = 0 | 1
Falls auf @code{0} gesetzt, wird für diesen Client kein Loggen in die
Update-Log-Datei durchgeführt, wenn der Client die
@strong{process}-Berechtigung hat. Das betrifft nicht das Standard-Log!

@item SQL_QUOTE_SHOW_CREATE = 0 | 1
Falls auf @code{1} gesetzt, setzt @code{SHOW CREATE TABLE} Tabellen- und
Spaltennamen in Anführungszeichen. Das ist vorgabemäßig
@strong{angeschaltet}, damit Replikation von Tabellen mit merkwürdigen
Spaltennamen funktioniert. @ref{SHOW CREATE TABLE, , @code{SHOW CREATE TABLE}}.

@item TIMESTAMP = zeitstempel_wert | DEFAULT
Setzt die Zeit für diesen Client. Das wird benutzt, um den
Original-Zeitstempel zu erhalten, wenn sie die Update-Log-Datei benutzen,
um Zeilen wiederherzustellen. @code{zeitstempel_wert} sollte ein
UNIX-Epoche-Zeitstempel sein, kein MySQL-Zeitstempel.

@item LAST_INSERT_ID = #
Setzt den Wert, der von @code{LAST_INSERT_ID()} zurückgegeben wird. Dieser
wird in der Update-Log-Datei gespeichert, wenn Sie @code{LAST_INSERT_ID()}
in einem Befehl benutzen, der eine Tabelle aktualisiert.

@item INSERT_ID = #
Setzt den Wert, der von einem folgenden @code{INSERT}- oder @code{ALTER
TABLE}-Befehl benutzt wird, wenn ein @code{AUTO_INCREMENT}-Wert eingefügt
wird. Das wird hauptsächlich zusammen mit der Update-Log-Datei benutzt.
@end table






@node Disk issues,  , Optimising the Server, MySQL Optimisation
@c German node Festplatte
@section Festplatte, Anmerkungen

@cindex Festplatten, Anmerkungen
@cindex Performance, Anmerkungen zur Festplatte

@itemize @bullet
@item
Wie bereits erwähnt sind Suchvorgänge auf der Festplatte ein großer
Performance-Flaschenhals. Die Probleme werden mehr und mehr deutlich, wenn
die Datenmenge wächst, so dass effizientes Caching unmöglich wird. Bei
großen Datenbanken, in denen Sie auf Daten mehr oder weniger zufällig
zugreifen, können Sie sicher davon ausgehen, dass Sie zumindest eine
Plattenzugriff brauchen, um zu lesen, und eine Reihe weiterer
Plattenzugriffe, um Dinge zu schreiben. Um dieses Problem zu minimieren,
benutzen Sie Platten mit geringen Zugriffszeiten!

@item
Erhöhen Sie die Anzahl verfügbarer Festplattenscheiben (und verringern Sie
dadurch den Such-Overhead), indem Sie entweder Dateien auf andere Platten
symbolisch verknüpfen (SymLink) oder die Platten 'stripen'.

@table @strong
@item Using Symbolische Links
Das bedeutet, dass Sie die Index- und / oder Daten-Datei(en) aus dem
normalen Daten-Verzeichnis auf eine andere Festplatte verknüpfen (die auch
'gestriped' sein kann). Das macht sowohl den Suchvorgang als auch die
Lesezeiten besser (wenn die Platten nicht für andere Dinge benutzt werden).
@xref{Symbolic links}.

@cindex Stripen, Definition
@item Stripen
'Stripen' heißt, dass Sie viele Festplatten haben und den ersten Block
auf die erste Platte legen, den zweiten Block auf die zweite Platte und den
n-ten Block auf die n-te Platte usw. Das bedeutet, wenn Ihre normale
Datengröße weniger als die Stripe-Größe ist (oder perfekt passt), dass
Sie wesentlich bessere Performance erhalten. Beachten Sie, dass Stripen
sehr stark vom Betriebssystem und von der Stripe-Größe abhängig ist.
Machen Sie Benchmark-Tests Ihrer Applikation mit unterschiedlichen
Stripe-Größen. @xref{Custom Benchmarks}.

Beachten Sie, dass der Geschwindigkeitsunterschied für das Stripen
@strong{sehr} stark vom Parameter abhängig ist. Abhängig davon, wie Sie den
Stripe-Parameter setzen und von der Anzahl von Festplatten erhalten Sie
Unterschiede in der Größenordnung von Faktoren. Beachten Sie, dass Sie
entscheiden müssen, ob Sie für zufällige oder sequentielle Zugriffe
optimieren.
@end table

@item
Aus Gründen der Zuverlässigkeit sollten sie vielleicht RAID 0 + 1 nehmen
(Stripen + Spiegeln), doch in diesem Fall brauchen Sie 2 * n Laufwerke, um
n Datenlaufwerke zu haben. Das ist wahrscheinlich die beste Option, wenn
Sie genug Geld dafür haben! Sie müssen jedoch eventuell zusätzlich in
Software für die Verwaltung von Volumes investieren, um das effizient zu
handhaben.

@item
Eine gute Option ist es, nicht ganz so wichtige Daten (die wieder
hergestellt werden können) auf RAID-0-Platten zu halten, während wirklich
wichtige Daten (wie Host-Informationen und Log-Dateien) auf einer RAID-0+1-
oder RAID-N-Platte gehalten werden. RAID-N kann ein Problem darstellen,
wenn Sie viele Schreibzugriffe haben, weil Zeit benötigt wird, die
Paritätsbits zu aktualisieren.

@item
Sie können auch den Parameter für das Dateisystem setzen, das die Datenbank
benutzt. Eine einfache Änderung ist, das Dateisystem mit der noatime-Option
zu mounten. Das bringt es dazu, das Aktualisieren der letzten Zugriffszeit
in der Inode zu überspringen und vermeidet dadurch einige
Platten-Suchzugriffe.

@item
Unter Linux können Sie viel mehr Performance erhalten (bis zu 100% unter
Last ist nicht ungewöhnlich), wenn Sie hdpram benutzen, um die
Schnittstelle Ihrer Festplatte zu konfigurieren! Das folgende Beispiel
sollte recht gute hdparm-Optionen für MySQL (und wahrscheinlich viele
andere Applikationen) darstellen:

@example
hdparm -m 16 -d 1
@end example

Beachten Sie, dass Performance und Zuverlässigkeit beim oben Genannten von
Ihrer Hardware abhängen, daher empfehlen wir sehr, dass Sie Ihr System
gründlich testen, nachdem Sie @code{hdparm} benutzt haben! Sehen Sie in der
Handbuchseite (ManPage) von @code{hdparm} nach weiteren Informationen! Wenn
@code{hdparm} nicht vernünftig benutzt wird, kann das Ergebnis eine
Beschädigung des Dateisystems sein. Machen Sie eine Datensicherung von
allem, bevor Sie experimentieren!

@item
Auf vielen Betriebssystemen können Sie die Platten mit dem 'async'-Flag
mounten, um das Dateisystem auf asynchrone Aktualisierung zu setzen. Wenn
Ihr Computer ausreichend stabil ist, sollte Ihnen das mehr Performance
geben, ohne zu viel Zuverlässigkeit zu opfern. (Dieser Flag ist unter Linux
vorgabemäßig angeschaltet.)

@item
Wenn Sie nicht wissen müssen, wann auf eine Datei zuletzt zugegriffen
wurden (was auf einem Datenbank-Server nicht wirklich nötig ist), können
Sie Ihr Dateisystem mit dem noatime-Flag mounten.
@end itemize



@menu
* Symbolic links::              
@end menu

@node Symbolic links,  , Disk issues, Disk issues
@c German node Symbolische Links
@subsection Symbolische Links benutzen

@cindex Symbolische Links
@cindex Links, symbolische

Sie können Tabellen und Datenbanken vom Datenbank-Verzeichnis an andere
Stellen verschieben und sie mit symbolischen Links auf neue Speicherorte
ersetzen. Das könnten Sie zum Beispiel tun, um eine Datenbank auf ein
Dateisystem mit mehr freiem Speicherplatz zu verlagern oder um die
Geschwindigkeit Ihres System durch Verteilen Ihrer Tabellen auf
unterschiedliche Platten zu steigern.

Die empfohlene Art, das zu tun, ist, nur Datenbanken auf unterschiedliche
Platten per SymLink zu verknüpfen, und das bei Tabellen nur im Notfall zu
tun.

@cindex Datenbanken, Symbolische Links


@menu
* Symbolic links to databases::  
* Symbolic links to tables::    
@end menu

@node Symbolic links to databases, Symbolic links to tables, Symbolic links, Symbolic links
@c German node Symbolische Links auf Datenbanken
@subsubsection Benutzung symbolischer Links für Datenbanken

Um eine Datenbank per SymLink zu verknüpfen, legt man zuerst ein
Verzeichnis auf einer Platte mit freiem Speicherplatz an und erzeugt dann
einen SymLink vom MySQL-Datenbank-Verzeichnis aus darauf:

@example
shell> mkdir /dr1/datenbanken/test
shell> ln -s /dr1/datenbanken/test mysqld-datadir
@end example

MySQL unterstützt nicht das Verknüpfen eines Verzeichnisses zu mehrfachen
Datenbanken. Wenn Sie ein Datenbank-Verzeichnis mit einem symbolischen Link
ersetzen, funktioniert das solange gut, wie Sie keinen symbolischen Link
zwischen Datenbanken machen. Angenommen, Sie haben eine Datenbank
@code{datenbank1} unter dem MySQL-Daten-Verzeichnis und machen dann einen
Symlink @code{datenbank2}, der auf @code{datenbank1} zeigt:

@example
shell> cd /pfad/zu/datadir
shell> ln -s datenbank1 datenbank2
@end example

Jetzt erscheint für jede Tabelle @code{tabelle_a} in @code{datenbank1} auch
eine Tabelle @code{tabelle_a} in @code{datenbank2}. Wenn ein Thread
@code{datenbank1.tabelle_a} aktualisiert und ein anderer Thread
@code{datenbank2.tabelle_a} aktualisiert, gibt es Probleme.

Wenn Sie das wirklich brauchen, müssen Sie folgenden Code in
@file{mysys/mf_format.c} ändern:

@example
if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
@end example

zu:

@example
if (1)
@end example

Unter Windows können Sie interne symbolische Links auf Verzeichnisse
benutzen, indem Sie MySQL mit @code{-DUSE_SYMDIR} kompilieren. Das erlaubt
Ihnen, verschiedene Datenbanken auf verschiedene Platte zu legen.
@xref{Windows symbolic links}.


@node Symbolic links to tables,  , Symbolic links to databases, Symbolic links
@c German node Symbolische Links auf Tabellen
@subsubsection Benutzung symbolischer Links für Tabellen

@cindex Datenbanken, Symbolische Links

Vor MySQL 4.0 konnten Sie Tabellen nicht per SymLink verknüpfen, wenn Sie
nicht sehr sorgfältig dabei vorgingen. Das Problem liegt darin, dass bei
@code{ALTER TABLE}, @code{REPAIR TABLE} oder @code{OPTIMIZE TABLE} auf eine
per Symlink verknüpfte Datei die SymLinks entfernt und durch die
Original-Dateien verknüpft werden. Das geschieht, weil beim obigen Befehl
eine temporäre Datei im Datenbank-Verzeichnis erzeugt wird, und wenn der
Befehl ausgeführt ist, die Original-Datei durch die temporäre Datei
ersetzt wird.

Sie sollten Tabellen auf Systemen, die keinen vollständig funktionierenden
@code{realpath()}-Aufruf haben, nicht per SymLink verknüpfen. (Zumindest
Linux und Solaris unterstützen @code{realpath()}.)

In MySQL 4.0 werden Symlinks nur für @code{MyISAM}-Tabellen vollständig
unterstützt. Bei anderen Tabellentypen erhalten Sie wahrscheinlich
merkwürdige Probleme, wenn Sie einen der obigen Befehle ausführen.

Die Handhabung symbolischer Links in MySQL 4.0 funktioniert auf folgende
Art (das gilt meist nur für @code{MyISAM}-Tabellen):

@itemize @bullet
@item
Im Daten-Verzeichnis liegen immer die Tabellendefinitionsdatei und die
Daten-/Index-Dateien.

@item
Sie können die Index-Datei und die Daten-Datei unabhängig voneinander auf
unterschiedliche Verzeichnisse per SymLink verknüpfen.

@item
Das Erzeugen der SymLinks kann durch das Betriebssystem (wenn @code{mysqld}
nicht läuft) oder mit dem @code{INDEX/DATA
directory="pfad-zum-verzeichnis"}-Befehl in @code{CREATE TABLE}
durchgeführt werden. @xref{CREATE TABLE}.

@item
@code{myisamchk} ersetzt keinen Symlink mit der Index-/Datendatei, sondern
arbeitet direkt mit den Dateien, auf die die SymLinks verweisen. Jegliche
temporäre Dateien werden im selben Verzeichnis erzeugt, wo die
Daten-/Index-Datei ist.

@item
Wenn Sie eine Tabelle löschen, die Symlinks benutzt, werden sowohl der
Symlink als auch die Datei, auf die der SymLink zeigt, gelöscht. Das ist
ein guter Grund dafür, @code{mysqld} NICHT als Root laufen zu lassen und
niemandem zu erlauben, Schreibzugriff auf die MySQL-Datenbankverzeichnisse
zu haben.

@item
Wenn Sie eine Tabelle mit @code{ALTER TABLE RENAME} umbenennen und nicht
die Datenbank ändern, wird der Symlink im Datenbank-Verzeichnis auf den
neuen Namen umbenannt und die Daten-/Index-Datei wird entsprechend
umbenannt.

@item
Wenn Sie @code{ALTER TABLE RENAME} benutzen, um eine Tabelle in eine andere
Datenbank zu verschieben, wird die Tabelle in das andere
Datenbank-Verzeichnis verschoben und die alten SymLinks und die Dateien,
auf die sie zeigen, werden gelöscht.

@item
Wenn Sie keine Symlinks benutzen, sollten Sie die
@code{--skip-symlink}-Option für @code{mysqld} benutzen, damit niemand eine
Datei ausserhalb des @code{mysqld} Daten-Verzeichnisses löschen oder
umbenennen kann.
@end itemize

Dinge, die noch nicht unterstützt werden:

@cindex TODO, SymLinks
@itemize @bullet
@item
@code{ALTER TABLE} ignoriert alle @code{INDEX/DATA directory="pfad"}-Optionen.
@item
@code{CREATE TABLE} berichtet nicht, wenn eine Tabelle symbolische Links hat.
@item
@code{mysqldump} gibt die Information über symbolische Links nicht in der Ausgabe aus.
@item
@code{BACKUP TABLE} und @code{RESTORE TABLE} respektieren keine symbolischen Links.
@end itemize


@node Reference, Table types, MySQL Optimisation, Top
@c German node Referenz
@chapter MySQL-Sprachreferenz


MySQL hat eine sehr komplexe, aber intuitive und leicht zu erlernende
SQL-Schnittstelle. Dieses Kapitel beschreibt die verschiedenen Befehle,
Typen und Funktionen, die Sie kennen müssen, um MySQL effizient und
effektiv zu benutzen. Dieses Kapitel dient auch als Referenz für die
gesamte in MySQL beinhaltete Funktionalität. Um dieses Kapitel effektiv zu
nutzen, sollten Sie unter den verschiedenen Stichworten nachschlagen.


@menu
* Language Structure::          
* Column types::                
* Functions::                   
* Data Manipulation::           
* Data Definition::             
* Basic User Commands::         
* Transactional Commands::      
* Fulltext Search::             
* Query Cache::                 
@end menu

@node Language Structure, Column types, Reference, Reference
@c German node Sprachstruktur
@section Sprachstruktur



@menu
* Literals::                    
* Legal names::                 
* Name case sensitivity::       
* Variables::                   
* Comments::                    
* Reserved words::              
@end menu

@node Literals, Legal names, Language Structure, Language Structure
@c German node Literale
@subsection Literale: Wie Zeichenketten und Zahlen geschrieben werden

@cindex Zeichenketten, Definition
@cindex Zeichenketten, Fluchtzeichen (Escape-Zeichen)
@cindex Literale
@cindex Fluchtzeichen (Escape-Zeichen)
@cindex Backslash, Fluchtzeichen (Escape-Zeichen)



Dieser Abschnitt beschreibt die verschiedenen Arten, in MySQL Zeichenketten
und Zahlen zu schreiben. Ebenfalls enthalten sind die verschiedenen Nuancen
und Fallstricke, in denen man sich bei den grundlegenden Datentypen von
MySQL verfangen kann.


@menu
* String syntax::               
* Number syntax::               
* Hexadecimal values::          
* NULL values::                 
@end menu

@node String syntax, Number syntax, Literals, Literals
@c German node Zeichenketten-Syntax
@subsubsection Zeichenketten

Eine Zeichenkette ist eine Folge von Zeichen, die entweder von Apostrophs
(einfachen Anführungszeichen, @samp{'}) oder (doppelten) Anführungszeichen
(@samp{"}) umgeben ist (nur einfache Anführungszeichen, wenn Sie MySQL im
ANSI-Modus laufen lassen). Beispiele:

@example
'eine Zeichenkette'
"eine weitere Zeichenkette"
@end example

Innerhalb einer Zeichenkette haben bestimmte Folgen eine spezielle
Bedeutung. Jede dieser Folgen fängt mit einem Backslash (@samp{\}) an,
bekannt als @emph{Fluchtzeichen (Escape-Zeichen)}. MySQL erkennt folgende
Flucht-Folgen (Escape-Folgen):

@c these aren't really Funktionen, aber that's wahrscheinlich the most reasonable index
@table @code
@findex \0 (ASCII 0)
@findex NUL
@item \0
Ein ASCII-0- (@code{NUL}) Zeichen.

@findex \' (Apostroph)
@findex single quote (\')
@item \'
Ein Apostroph- (@samp{'}) Zeichen.

@findex \" (Anführungszeichen)
@findex Anführungszeichen (\")
@item \"
Ein Anführungszeichen (@samp{"}).

@findex \b (Rückschritt, Backspace)
@findex backspace (\b)
@item \b
Ein Rückschritt- (Backspace-) Zeichen.

@findex \n (neue Zeile)
@findex newline (\n)
@item \n
Ein Neue-Zeile- (Newline-) Zeichen.

@findex \r (Wagenrücklauf (carriage return))
@findex return (\r)
@findex Wagenrücklauf (carriage return) (\r)
@item \r
Ein Wagenrücklauf- (carriage return) Zeichen.

@findex \t (Tabulator)
@findex tab (\t)
@item \t
Ein Tabulator-Zeichen.

@findex \z (Steuerung-Z) ASCII(26)
@findex (Steuerung-Z) \z
@item \z
ASCII(26) (Steuerung-Z). Dieses Zeichen kann kodiert werden, um das Problem
zu umgehen, dass ASCII(26) unter Windows für Dateiende (END-OF-FILE) steht.
(ASCII(26) verursacht Probleme, wenn Sie @code{mysql Datenbank < Dateiname}
benutzen.)

@findex \\ (Fluchtzeichen, Escape-Zeichen)
@findex escape (\\)
@item \\
Ein Backslash- (@samp{\}) Zeichen.

@c German FIX added space before %
@findex % (Platzhalterzeichen)
@findex Wild card character (%)
@item \%
Ein @samp{%}-Zeichen. Dieses wird benutzt, um nach literalen Instanzen von
@samp{%} in Zusammenhängen zu suchen, wo @samp{%} ansonsten als
Platzhalterzeichen interpretiert werden würde.
@xref{String comparison functions}.

@findex _ (Platzhalterzeichen)
@findex Wild card character (_)
@item \_
Ein @samp{_}-Zeichen. Dieses wird benutzt, um nach literalen Instanzen von
@samp{_} in Zusammenhängen zu suchen, wo @samp{_} ansonsten als
Platzhalterzeichen interpretiert werden würde.
@xref{String comparison functions}.
@end table

Beachten Sie, dass bei der Benutzung von @samp{\%} oder @samp{\_} in
einigen Zeichenketten-Zusammenhängen diese die Zeichenketten @samp{\%} und
@samp{\_} und nicht @samp{%} und @samp{_} zurückgeben.

@cindex Anführungszeichen, in Zeichenketten
@noindent
Es gibt verschiedene Möglichkeiten, Anführungszeichen innerhalb einer
Zeichenkette zu schreiben:

@itemize @bullet
@item
Ein @samp{'} innerhalb einer Zeichenkette, die mit @samp{'} begrenzt wird,
kann als @samp{''} geschrieben werden.

@item
Ein @samp{"} innerhalb einer Zeichenkette, die @samp{"} begrenzt wird, kann
als @samp{""} geschrieben werden.

@item
Sie können dem Anführungszeichen ein Fluchtzeichen (Escape-Zeichen)
(@samp{\}) voranstellen.

@item
Ein @samp{'} innerhalb einer Zeichenkette, die mit @samp{"} begrenzt wird,
braucht keine spezielle Behandlung und muss nicht verdoppelt oder escapet
werden. In gleicher Weise benötigt @samp{"} innerhalb einer Zeichenkette,
die mit @samp{'} begrenzt wird, keine spezielle Behandlung.
@end itemize

Die unten stehenden @code{SELECT}-Statements zeigen, wie Quoten und Escapen
funktionieren:

@example
mysql> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+

mysql> SELECT "Das\nsind\nvier\nZeilen";
+--------------------+
| Das
sind
vier
Zeilen |
+--------------------+
@end example

@cindex Binärdaten quoten

Wenn Sie Binärdaten in eine @code{BLOB}-Spalte einfügen, müssen folgende
Zeichen durch Flucht-Folgen repräsentiert werden:
@table @code
@item NUL
ASCII 0. Dieses geben Sie als @samp{\0} ein (ein Backslash und ein
ASCII-@samp{0}-Zeichen).
@item \
ASCII 92, Backslash. Das geben Sie als @samp{\\} ein.
@item '
ASCII 39, Apostroph. Das geben Sie als @samp{\'} ein.
@item "
ASCII 34, Anführungszeichen. Das geben Sie als @samp{\"} ein.
@end table

@cindex Quoten
@cindex @code{BLOB}, Binärdaten einfügen
@findex mysql_escape_string()
@findex DBI->quote
Wenn Sie C-Code schreiben, können Sie die C-API-Funktion
@code{mysql_escape_string()} für Fluchtzeichen (Escape-Zeichen) für das
@code{INSERT}-Statement benutzen. @xref{C API function overview}. In Perl
können Sie die @code{quote}-Methode des @code{DBI}-Pakets benutzen, um
Sonderzeichen in die korrekten Flucht-Folgen umzuwandeln.
@xref{Perl DBI Class, , Perl-@code{DBI}-Klasse}.

Sie sollten auf jede Zeichenkette, die eins der oben erwähnten
Sonderzeichen enthalten könnte, eine der Flucht-Funktionen anwenden!


@node Number syntax, Hexadecimal values, String syntax, Literals
@c German node Zahlen-Syntax
@subsubsection Zahlen

@cindex Zahlen
@cindex gültige Zahlen, Beispiele
@cindex Ganzzahlen
@cindex Fließkommazahlen
@cindex negative Werte

Ganzzahlen werden als Folge von Ziffern repräsentiert. Fließkommazahlen
benutzen @samp{.} als Dezimalseparator. Jedem Zahlentyp kann @samp{-}
vorangestellt werden, um einen negativen Wert anzuzeigen.

Beispiele gültiger Ganzzahlen:

@example
1221
0
-32
@end example

Beispiele gültiger Fließkommazahlen:

@example
294.42
-32032.6809e+10
148.00
@end example

Eine Ganzzahl kann in einem Fließkomma-Zusammenhang benutzt werden, sie
wird dann als die äquivalente Fließkommazahl interpretiert.


@node Hexadecimal values, NULL values, Number syntax, Literals
@c German node Hexadezimale Werte
@subsubsection Hexadezimale Werte

@tindex hexadezimale Werte

MySQL unterstützt hexadezimale Werte. In Zahlen-Zusammenhängen
funktionieren diese wie eine Ganzzahl (64-Bit-Genauigkeit). Im
Zeichenketten-Zusammenhang funktionieren sie wie eine binäre Zeichenkette,
wobei jedes Paar hexadezimaler Ziffern in ein Zeichen umgewandelt wird:

@example
mysql> SELECT x'FF'
       -> 255
mysql> SELECT 0xa+0;
       -> 10
mysql> select 0x5061756c;
       -> Paul
@end example

Die x'hexadezimale_zeichenkette'-Syntax (neu in Version 4.0) basiert auf
ANSI-SQL. Die 0x-Syntax basiert auf ODBC. Hexadezimale Zeichenketten werden
oft von ODBC benutzt, um Werte für BLOB-Spalten anzugeben.


@node NULL values,  , Hexadecimal values, Literals
@c German node NULL-Werte
@subsubsection @code{NULL}-Werte

@tindex NULL-Wert

Der @code{NULL}-Wert bedeutet ``keine Daten'' und unterscheidet sich von
Werten wie @code{0} bei numerischen Typen oder der leeren Zeichenkette bei
Zeichenkettentypen. @xref{Problems with NULL, , Probleme mit @code{NULL}}.

@code{NULL} kann durch @code{\N} repräsentiert werden, wenn Sie die
Textdatei-Import- oder Exportformate (@code{LOAD DATA INFILE}, @code{SELECT
... INTO OUTFILE}) benutzen. @xref{LOAD DATA, , @code{LOAD DATA}}.


@node Legal names, Name case sensitivity, Literals, Language Structure
@c German node Erlaubte Namen
@subsection Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen

@cindex Namen
@cindex erlaubte Namen
@cindex Datenbanken, Namen
@cindex Tabellen, Namen
@cindex Indexe, Namen
@cindex Spalten, Namen
@cindex Aliase, Namen



Datenbank-, Tabellen-, Index-, Spalten- und Alias-Namen folgen in MySQL
alle denselben Regeln.

@tindex Bezeichner, quoten
@tindex Quoten von Bezeichnern
@tindex `
@tindex "
Beachten Sie, dass sich die Regeln ab MySQL-Version 3.23.6 geändert haben,
als das Quoten von Bezeichnern (für Datenbank-, Tabellen- und Spaltennamen)
eingeführt wurde, mit @samp{`}. @samp{"} funktioniert ebenfalls, um
Bezeichner zu quoten, wenn Sie im ANSI-Modus fahren. @xref{ANSI mode}.

@multitable @columnfractions .15 .15 .70
@item @strong{Bezeichner} @tab @strong{Maximale Länge} @tab @strong{Erlaubte Zeichen}
@item Datenbank @tab 64 @tab Jedes Zeichen, dass für ein Verzeichnis erlaubt ist, ausser @samp{/} oder @samp{.}.
@item Tabelle @tab 64 @tab Jedes Zeichen, dass für einen Dateinamen erlaubt ist, ausser @samp{/} oder @samp{.}.
@item Spalte @tab 64 @tab Alle Zeichen.
@item Alias @tab 255 @tab Alle Zeichen.
@end multitable

Hinzuzufügen ist, dass Sie ASCII(0), ASCII(255) oder das Quote-Zeichen in
einem Bezeichner nicht verwenden dürfen.

Beachten Sie, dass, falls der Bezeichner ein reserviertes Wort ist oder
Sonderzeichen enthält, er bei der Benutzung immer in @code{`} angegeben
sein muss:

@example
SELECT * from `select` where `select`.id > 100;
@end example

In vorherigen Versionen von MySQL sind die Namensregeln wie folgt:

@itemize @bullet
@item
Ein Name muss aus alphanumerischen Zeichen des aktuellen Zeichensatzes
bestehen und darf darüber hinaus @samp{_} und @samp{$} enthalten. Der
vorgabemäßige Zeichensatz ist ISO-8859-1 Latin1; dass kann durch die
@code{--default-character-set}-Option für @code{mysqld} geändert werden.
@xref{Character sets}.

@item
Ein Name kann mit jedem Zeichen anfangen, das in einem Namen erlaubt ist.
Insbesondere kann ein Name auch mit einer Zahl anfangen (das ist in vielen
anderen Datenbanksystemen anders!). Jedoch kann ein Namen nicht @emph{nur}
aus Zahlen bestehen.

@item
Sie können das @samp{.}-Zeichen in Namen nicht benutzen, weil es benutzt
wird, um das Format zu erweitern, mit dem man auf Spalten verweisen kann
(siehe unten).
@end itemize

Es wird empfohlen, dass Sie keine Namen wie @code{1e} verwenden, weil ein
Ausdruck wie @code{1e+1} mehrdeutig ist. Er kann als der Ausdruck @code{1e
+ 1} oder als die Zahl @code{1e+1} interpretiert werden.

In MySQL können Sie in folgender Form auf Spalten verweisen:

@multitable @columnfractions .35 .65
@item @strong{Spaltenverweis} @tab @strong{Bedeutung}
@item @code{spalten_name} @tab Spalte des Namens @code{spalten_name} einer
beliebigen, in der Anfrage verwendeten Tabelle.
@item @code{tabelle.spalten_name} @tab Spalte des Namens
@code{spalten_name} der Tabelle @code{tabelle} der aktuellen Datenbank.
@item @code{datenbank.tabelle.spalten_name} @tab Spalte des Namens
@code{spalten_name} der Tabelle @code{tabelle} der Datenbank
@code{datenbank}. Diese Form ist ab MySQL-Version 3.22 verfügbar.
@item
@code{`spalte`} @tab Eine Spalte, die ein reserviertes Wort ist oder
Sonderzeichen enthält.
@end multitable

Das @code{tabelle}- oder @code{datenbank.tabelle}-Präfix müssen Sie bei
einem Spaltenverweis in einem Statement nicht angeben, es sei denn, der
Verweis wäre ansonsten doppeldeutig. Nehmen Sie zum Beispiel an, die
Tabellen @code{t1} und @code{t2} enthielten beide jeweils eine Spalte
@code{c} und Sie verweisen auf @code{c} in einem @code{SELECT}-Statement,
das sowohl @code{t1} als auch @code{t2} benutzt. In diesem Fall ist
@code{c} mehrdeutig, weil es innerhalb der im Statement benutzten Tabellen
nicht eindeutig ist. Daher müssen Sie angeben, welche Tabelle Sie meinen,
indem Sie @code{t1.c} oder @code{t2.c} schreiben. Ähnliches gilt, wenn Sie
aus einer Tabelle @code{t} in Datenbank @code{datenbank1} und von eine
Tabelle @code{t} in Datenbank @code{datenbank2} abrufen. Dann müssen Sie
auf Spalten in diesen Tabellen als @code{datenbank1.t.spalten_name} und
@code{datenbank2.t.spalten_name} verweisen.

@cindex ODBC Kompatibilität
@cindex Kompatibilität, mit ODBC
Die Syntax @code{.tabelle} bedeutet die Tabelle @code{tabelle} in der
aktuellen Datenbank. Diese Syntax wird aus Gründen der ODBC-Kompatibilität
akzeptiert, weil einige ODBC-Programme Tabellenname ein @samp{.}-Zeichen
voranstellen.


@node Name case sensitivity, Variables, Legal names, Language Structure
@c German node Groß-/Kleinschreibung in Namen
@subsection Groß-/Kleinschreibung in Namen

@cindex Namen, Groß-/Kleinschreibung
@cindex Groß-/Kleinschreibung, in Namen
@cindex Datenbanknamen, Groß-/Kleinschreibung
@cindex Tabellennamen, Groß-/Kleinschreibung
@cindex Spaltennamen, Groß-/Kleinschreibung
@cindex Aliasnamen, Groß-/Kleinschreibung

In MySQL entsprechen Datenbanken und Tabellen Verzeichnissen und Dateien
innerhalb dieser Verzeichnisse. Folglich hängt die Groß-/Kleinschreibung
davon ab, wie das zugrunde liegende Betriebssystem die
Groß-/Kleinschreibung von Datenbank- und Tabellennamen festlegt. Das
bedeutet, dass Datenbank- und Tabellennamen unter Unix von der
Groß-/Kleinschreibung abhängen und unter Windows nicht.
@xref{Extensions to ANSI}.

@strong{HINWEIS:} Obwohl die Groß-/Kleinschreibung für Datenbank- und
Tabellennamen unter Windows keine Rolle spielt, sollten Sie nicht auf eine
angegebene Datenbank oder Tabelle innerhalb derselben Anfrage mit
unterschiedlicher Schreibweise verweisen. Folgende Anfrage würde nicht
funktionieren, weil sie auf eine Tabelle sowohl mit @code{meine_tabelle}
als auch mit @code{MEINE_TABELLE} verweist:

@example
mysql> SELECT * FROM meine_tabelle WHERE MEINE_TABELLE.spalte=1;
@end example

Spaltennamen hängen in keinem Fall von der verwendeten
Groß-/Kleinschreibung ab.

Aliase auf Tabellen hängen von der Groß-/Kleinschreibung ab. Folgende
Anfrage würde nicht funktionieren, weil sie auf den Alias sowohl mit
@code{a} als auch mit @code{A} verweist:

@example
mysql> SELECT spalten_name FROM tabelle AS a
           WHERE a.spalten_name = 1 OR A.spalten_name = 2;
@end example

Aliase auf Spalten hängen nicht von der verwendeten Groß-/Kleinschreibung
ab.

Wenn Sie Probleme damit haben, sich an die Schreibweise von Tabellennamen zu
erinnern, halten Sie sich an eine durchgehende Konvention. Benutzen Sie zum
Beispiel bei der Erzeugung von Datenbanken und Tabellen Kleinschreibung in
Namen.

Eine Möglichkeit, dieses Problem zu vermeiden, ist, @code{mysqld} mit
@code{-O lower_case_tabelles=1} zu starten. Vorgabemäßig ist diese Option
1 unter Windows und 0 unter Unix.

Wenn @code{lower_case_tabelles} 1 ist, wandelt MySQL alle Tabellennamen in
Kleinschreibung um, sowohl beim Speichern als auch beim Nachschlagen. Wenn
Sie diese Option ändern, beachten Sie, dass Sie zuerst Ihre alten
Tabellennamen in Kleinschreibung umwandeln müssen, bevor Sie @code{mysqld}
starten.


@node Variables, Comments, Name case sensitivity, Language Structure
@c German node Variablen
@subsection Benutzer-Variablen

@cindex Variablen, Benutzer-
@cindex Benutzer-Variablen
@cindex Namen, Variablen

MySQL unterstützt Thread-spezifische Variablen mit der
@code{@@variablename}-Syntax. Eine Variable kann aus alphanumerischen
Zeichen des aktuellen Zeichensatzes sowie aus @samp{_}, @samp{$} und
@samp{.} bestehen. Der vorgabemäßige Zeichensatz ist ISO-8859-1 Latin1;
das kann mit der @code{--default-character-set}-Option für @code{mysqld}
geändert werden. @xref{Character sets}.

Variablen müssen nicht initialisiert werden. Sie enthalten vorgabemäßig
@code{NULL} und können Ganzzahl-, Real- oder Zeichenketten-Werte speichern.
Alle Variablen für einen Thread werden automatisch freigegeben, wenn der
Thread beendet wird.

Sie können eine Variable mit der @code{SET}-Syntax setzen:

@example
SET @@variable= @{ ganzzahl_ausdruck | realzahl_ausdruck | zeichenketten_ausdruck @} [,@@variable= ...].
@end example

Sie können eine Variable in einem Ausdruck auch mit der
@code{@@variable:=expr}-Syntax setzen:

@example
select @@t1:=(@@t2:=1)+@@t3:=4,@@t1,@@t2,@@t3;
+----------------------+------+------+------+
| @@t1:=(@@t2:=1)+@@t3:=4 | @@t1  | @@t2  | @@t3  |
+----------------------+------+------+------+
|                    5 |    5 |    1 |    4 |
+----------------------+------+------+------+
@end example

(Wir mussten hier die @code{:=}-Syntax benutzen, weil @code{=} für
Vergleiche reserviert ist.)

Benutzer-Variablen können benutzt werden, wo Ausdrücke erlaubt sind.
Beachten Sie, dass das momentan keine Zusammenhänge einschließt, in denen
explizit Zahlen erforderlich sind, wie in der @code{LIMIT}-Klausel eines
@code{SELECT}-Statements oder der @code{IGNORE Anzahl LINES}-Klausel eines
@code{LOAD DATA}-Statements.

@strong{HINWEIS:}  In einem @code{SELECT}-Statement wird jeder Ausdruck
erst dann ausgewertet, wenn er an den Client geschickt wird. Das heißt,
dass Sie in der @code{HAVING}-, @code{GROUP BY}- oder @code{ORDER
BY}-Klausel nicht auf einen Ausdruck verweisen können, der Variablen
beinhaltet, die nicht im @code{SELECT}-Teil gesetzt wurden. Folgendes
Statement zum Beispiel funktioniert erwartungsgemäß NICHT:

@example
SELECT (@@aa:=id) AS a, (@@aa+3) AS b FROM tabelle HAVING b=5;
@end example

Der Grund ist, dass @code{@@aa} nicht den Wert der aktuellen Zeile enthält,
sondern den Wert von @code{id} der vorher akzeptierten Zeile.



@node Comments, Reserved words, Variables, Language Structure
@c German node Kommentare
@subsection Kommentar-Syntax

@findex Kommentar-Syntax

@cindex Kommentare, hinzufügen

Der MySQL-Server die Kommentar-Stile @code{# bis Zeilenende}, @code{-- bis
Zeilenende} und @code{/* mittendrin oder mehrzeilig */}:

@example
mysql> select 1+1;     # Dieser Kommentar geht bis zum Zeilenende
mysql> select 1+1;     -- Dieser Kommentar geht bis zum Zeilenende
mysql> select 1 /* Das ist ein Kommentar mittendrin */ + 1;
mysql> select 1+
/*
Das ist ein
mehrzeiliger
Kommentar
*/
1;
@end example

Beachten Sie, dass Sie beim Kommentarstil @code{--} mindestens ein
Leerzeichen hinter @code{--} setzen müssen!

Obwohl der Server die Kommentar-Syntax wie beschrieben versteht, gibt es
einige Einschränkungen in der Art, wie der @code{mysql}-Client @code{/* ...
*/}-Kommentare parst:

@itemize @bullet
@item
Einfache und doppelte Anführungszeichen werden genommen, um den Anfang
einer Zeichenkette zu bestimmen, selbst innerhalb eines Kommentars. Wenn
die Zeichenkette nicht durch ein zweites Anführungszeichen innerhalb des
Kommentars abgeschlossen wird, bemerkt der Parser nicht, dass der Kommentar
zuende ist. Wenn Sie @code{mysql} interaktiv ausführen, sehen Sie, dass
@code{mysql} verwirrt ist, weil sich die Eingabeaufforderung von
@code{mysql>} zu to @code{'>} oder @code{">} ändert.

@item
Ein Semikolon wird genommen, um das Ende des aktuellen SQL-Statements
kenntlich zu machen. Alles Folgende wird als Anfang des nächsten Statements
aufgefasst.
@end itemize

Diese Einschränkungen gelten sowohl, wenn Sie @code{mysql} interaktiv
ausführen und wenn Sie Befehle in eine Datei schreiben und @code{mysql} mit
@code{mysql < some-file} anweisen, seine Eingaben aus dieser Datei zu
lesen.

MySQL unterstützt nicht den ANSI-SQL-Kommentarstil @samp{--} ohne
nachfolgendes Leerzeichen. @xref{ANSI diff comments}.


@node Reserved words,  , Comments, Language Structure
@c German node Reservierte Wörter
@subsection Ist MySQL pingelig hinsichtlich reservierter Wörter?

@cindex Schlüsselwörter
@cindex reservierte Wörter, Ausnahmen

Ein häufiges Problem rührt daher, dass versucht wird, eine Tabelle mit
Spaltennamen zu erzeugen, den die Namen von Datentypen oder in MySQL
eingebauten Funktionen entsprechen, wie @code{TIMESTAMP} oder @code{GROUP}.
Sie dürfen das tun (beispielsweise ist @code{ABS} ein zulässiger
Spaltenname), aber es sind dann keine Leerzeichen zwischen einem
Funktionsname und der @samp{(} erlaubt, wenn Sie Funktionen benutzen, deren
Namen auch Spaltennamen sind.

Folgende Wörter sind in MySQL explizit reserviert. Die meisten davon sind
in ANSI-SQL92 als Spalten- und / oder Tabellennamen verboten (zum Beispiel
@code{group}). Einige wenige sind reserviert, weil MySQL sie benötigt und
(momentan) einen @code{yacc}-Parser benutzt:

@c This ist fixed von including the symbols Tabelle von lex.h here und then running
@c fix-mysql-reserved-words in emacs (or let David do it):
@c (defun fix-mysql-reserved-words ()
@c  (interactive)
@c  (let ((cnt 0))
@c    (insert "\n@item ")
@c    (while (looking-at "[ \t]*{ +\"\\([^\"]+\\)\"[ \t]*,.*\n")
@c      (replace-match "@code{\\1}")
@c      (incf cnt)
@c      (if (> cnt 3)
@c 	  (progn
@c 	    (setf cnt 0)
@c 	    (insert "\n@item "))
@c 	(insert " @tab ")))))
@c But remove the non alphanumeric Einträge von Hand first.
@c Updated after 3.23.4 990928 von David

@multitable @columnfractions .25 .25 .25 .25
@item @code{action} @tab @code{add} @tab @code{aggregate} @tab @code{all}
@item @code{alter} @tab @code{after} @tab @code{and} @tab @code{as}
@item @code{asc} @tab @code{avg} @tab @code{avg_row_length} @tab @code{auto_increment}
@item @code{between} @tab @code{bigint} @tab @code{bit} @tab @code{binary}
@item @code{blob} @tab @code{bool} @tab @code{both} @tab @code{by}
@item @code{cascade} @tab @code{case} @tab @code{char} @tab @code{character}
@item @code{change} @tab @code{check} @tab @code{checksum} @tab @code{column}
@item @code{columns} @tab @code{comment} @tab @code{constraint} @tab @code{create}
@item @code{cross} @tab @code{current_date} @tab @code{current_time} @tab @code{current_timestamp}
@item @code{data} @tab @code{database} @tab @code{databases} @tab @code{date}
@item @code{datetime} @tab @code{day} @tab @code{day_hour} @tab @code{day_minute}
@item @code{day_second} @tab @code{dayofmonth} @tab @code{dayofweek} @tab @code{dayofyear}
@item @code{dec} @tab @code{decimal} @tab @code{default} @tab @code{delayed}
@item @code{delay_key_write} @tab @code{delete} @tab @code{desc} @tab @code{describe}
@item @code{distinct} @tab @code{distinctrow} @tab @code{double} @tab @code{drop}
@item @code{end} @tab @code{else} @tab @code{escape} @tab @code{escaped}
@item @code{enclosed} @tab @code{enum} @tab @code{explain} @tab @code{exists}
@item @code{fields} @tab @code{file} @tab @code{first} @tab @code{float}
@item @code{float4} @tab @code{float8} @tab @code{flush} @tab @code{foreign}
@item @code{from} @tab @code{for} @tab @code{full} @tab @code{Funktion}
@item @code{global} @tab @code{grant} @tab @code{grants} @tab @code{group}
@item @code{having} @tab @code{heap} @tab @code{high_priority} @tab @code{hour}
@item @code{hour_minute} @tab @code{hour_second} @tab @code{hosts} @tab @code{identified}
@item @code{ignore} @tab @code{in} @tab @code{index} @tab @code{infile}
@item @code{inner} @tab @code{insert} @tab @code{insert_id} @tab @code{int}
@item @code{integer} @tab @code{interval} @tab @code{int1} @tab @code{int2}
@item @code{int3} @tab @code{int4} @tab @code{int8} @tab @code{into}
@item @code{if} @tab @code{is} @tab @code{isam} @tab @code{join}
@item @code{key} @tab @code{keys} @tab @code{kill} @tab @code{last_insert_id}
@item @code{leading} @tab @code{left} @tab @code{length} @tab @code{like}
@item @code{lines} @tab @code{limit} @tab @code{load} @tab @code{local}
@item @code{lock} @tab @code{logs} @tab @code{long} @tab @code{longblob}
@item @code{longtext} @tab @code{low_priority} @tab @code{max} @tab @code{max_rows}
@item @code{match} @tab @code{mediumblob} @tab @code{mediumtext} @tab @code{mediumint}
@item @code{middleint} @tab @code{min_rows} @tab @code{minute} @tab @code{minute_second}
@item @code{modify} @tab @code{month} @tab @code{monthname} @tab @code{myisam}
@item @code{natural} @tab @code{numeric} @tab @code{no} @tab @code{not}
@item @code{null} @tab @code{on} @tab @code{optimize} @tab @code{option}
@item @code{optionally} @tab @code{or} @tab @code{order} @tab @code{outer}
@item @code{outfile} @tab @code{pack_keys} @tab @code{partial} @tab @code{password}
@item @code{precision} @tab @code{primary} @tab @code{procedure} @tab @code{process}
@item @code{processlist} @tab @code{privileges} @tab @code{read} @tab @code{real}
@item @code{references} @tab @code{reload} @tab @code{regexp} @tab @code{rename}
@item @code{replace} @tab @code{restrict} @tab @code{returns} @tab @code{revoke}
@item @code{rlike} @tab @code{row} @tab @code{rows} @tab @code{second}
@item @code{select} @tab @code{set} @tab @code{show} @tab @code{shutdown}
@item @code{smallint} @tab @code{soname} @tab @code{sql_big_tables} @tab @code{sql_big_selects}
@item @code{sql_low_priority_updates} @tab @code{sql_log_off} @tab @code{sql_log_update} @tab @code{sql_select_limit}
@item @code{sql_small_result} @tab @code{sql_big_result} @tab @code{sql_warnings} @tab @code{straight_join}
@item @code{starting} @tab @code{status} @tab @code{string} @tab @code{table}
@item @code{tables} @tab @code{temporary} @tab @code{terminated} @tab @code{text}
@item @code{then} @tab @code{time} @tab @code{timestamp} @tab @code{tinyblob}
@item @code{tinytext} @tab @code{tinyint} @tab @code{trailing} @tab @code{to}
@item @code{type} @tab @code{use} @tab @code{using} @tab @code{unique}
@item @code{unlock} @tab @code{unsigned} @tab @code{update} @tab @code{usage}
@item @code{values} @tab @code{varchar} @tab @code{variables} @tab @code{varying}
@item @code{varbinary} @tab @code{mit} @tab @code{write} @tab @code{when}
@item @code{where} @tab @code{year} @tab @code{year_month} @tab @code{zerofill}
@end multitable

Folgende Symbole (aus der obigen Tabelle) sind von ANSI-SQL verboten, aber
von MySQL als Spalten- und Tabellennamen zugelassen. Der Grund ist, dass
einige davon sehr natürliche Namen sind und viele Leute diese bereits in
Benutzung haben.

@itemize @bullet
@item @code{ACTION}
@item @code{BIT}
@item @code{DATE}
@item @code{ENUM}
@item @code{NO}
@item @code{TEXT}
@item @code{TIME}
@item @code{TIMESTAMP}
@end itemize


@node Column types, Functions, Language Structure, Reference
@c German node Spaltentypen
@section Spaltentypen

@cindex Spalten, Typen
@cindex Typen, Spalten

MySQL unterstützt eine Reihe von Spaltentypen, die in drei Kategorien
eingeteilt werden können: numerische Typen, Datums- und Zeit-Typen und
Zeichenketten-Typen. Dieser Abschnitt gibt zuerst einen Überblick über die
verfügbaren Typen und fasst den Speicherbedarf jedes Spaltentyps zusammen.
Danach folgt eine detaillierter Beschreibung der Eigenschaften der Typen
jeder Kategorie. Die detailliertere Beschreibung sollte wegen zusätzlicher
Informationen über bestimmte Spaltentypen herangezogen werden, wie zu den
erlaubten Formaten, in denen Sie Werte festlegen können.

Die von MySQL unterstützten Spaltentypen sind unten aufgeführt. Folgende
Code-Buchstaben werden in der Beschreibung benutzt:

@cindex Anzeigebreite
@cindex Größe, Anzeigebreite
@cindex Ziffern
@cindex Dezimalpunkt
@cindex Klammern, eckige
@cindex eckige Klammern
@table @code
@item M
Gibt die maximale Anzeigebreite an. Die größte erlaubte Anzeigebreite ist
255.

@item D
Trifft auf Fließkomma-Typen zu und bezeichnet die Anzahl von Ziffern nach
dem Dezimalpunkt. Der größte mögliche Wert ist 30, aber er sollte nicht
größer sein als @code{M}-2.
@end table

Eckige Klammern (@samp{[} und @samp{]}) geben Teile der Typ-Festlegung an,
die optional sind.

@tindex Typen

@c The @w{-Anzahl} stuff keeps a linebreak von occurring between
@c the - und Anzahl.

Wenn Sie @code{ZEROFILL} für eine Spalte angeben, beachten Sie, dass MySQL
der Spalte automatisch ein @code{UNSIGNED}-Attribut hinzufügt.

@table @code
@tindex TINYINT
@item TINYINT[(M)] [UNSIGNED] [ZEROFILL]

Eine sehr kleine Ganzzahl. Der vorzeichenbehaftete Bereich ist @code{-128}
bis @code{127}. Der vorzeichenlose Bereich ist @code{0} to @code{255}.

@tindex SMALLINT
@item SMALLINT[(M)] [UNSIGNED] [ZEROFILL]

Eine kleine Ganzzahl. Der vorzeichenbehaftete Bereich ist @code{-32768} bis
@code{32767}. Der vorzeichenlose Bereich ist @code{0} bis @code{65535}.

@tindex MEDIUMINT
@item MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]

A Ganzzahl mittlerer Größe. Der vorzeichenbehaftete Bereich ist
@code{-8388608} bis @code{8388607}. Der vorzeichenlose Bereich ist @code{0}
bis @code{16777215}.

@tindex INT
@item INT[(M)] [UNSIGNED] [ZEROFILL]

Eine Ganzzahl normaler Größe. Der vorzeichenbehaftete Bereich ist
@code{-2147483648} bis @code{2147483647}. Der vorzeichenlose Bereich ist
@code{0} bis @code{4294967295}.

@tindex INTEGER
@item INTEGER[(M)] [UNSIGNED] [ZEROFILL]

Ein Synonym für @code{INT}.

@tindex BIGINT
@item BIGINT[(M)] [UNSIGNED] [ZEROFILL]

Eine große Ganzzahl. Der vorzeichenbehaftete Bereich ist
@code{-9223372036854775808} bis @code{9223372036854775807}. Der
vorzeichenlose Bereich ist @code{0} bis @code{18446744073709551615}.

Einiger Dinge sollten Sie sich bei @code{BIGINT}-Spalten bewusst sein:

@itemize @bullet
@item
@cindex Rundungsfehler
Weil alle arithmetischen Berechnungen mit vorzeichenbehafteten
@code{BIGINT}- oder @code{DOUBLE}-Werten durchgeführt werden, sollten Sie
keine vorzeichenlosen Ganzzahlen größer als @code{9223372036854775807} (63
Bits) benutzen, ausser bei Bit-Funktionen! Wenn Sie das doch tun, können
einige der letzten Ziffern im Ergebnis falsch sein, weil Rundungsfehler
beim Umwandeln von @code{BIGINT} in @code{DOUBLE} auftreten.

MySQL 4.0 kann @code{BIGINT} in folgenden Fällen handhaben:
@itemize @bullet
@item
Benutzen Sie Ganzzahlen, um große vorzeichenlose Wert in einer
@code{BIGINT}-Spalte zu speichern.
@item
Bei @code{MIN(große_ganzzahl_spalte)} und
@code{MAX(große_ganzzahl_spalte)}.
@item
Bei der Benutzung der Operatoren (@code{+}, @code{-}, @code{*} usw.), wenn
beide Operanden Ganzzahlen sind.
@end itemize

@item
Sie können immer einen genauen Ganzzahlwert in einer @code{BIGINT}-Spalte
speichern, wenn Sie sie als Zeichenkette speichern, denn in diesem Fall
wird diese nicht zwischendurch als Double dargestellt.
@item
@samp{-}, @samp{+} und @samp{*} benutzen arithmetische
@code{BIGINT}-Berechnungen, wenn beide Argumente @code{INTEGER}-Werte sind!
Das heißt, wenn Sie zwei Ganzzahlen multiplizieren (oder Ergebnisse von
Funktionen, die Ganzzahlen zurückgeben), erhalten Sie vielleicht
unerwartete Ergebnisse, wenn das Ergebnis größer als
@code{9223372036854775807} ist.
@end itemize

@cindex Fließkommazahl
@tindex FLOAT
@tindex FLOAT(genauigkeit)
@item FLOAT(genauigkeit) [ZEROFILL]

Eine Fließkommazahl. Kann nicht vorzeichenlos sein. @code{genauigkeit} ist
@code{<=24} bei einer Fließkommazahl einfacher Genauigkeit und zwischen 25
und 53 bei einer Fließkommazahl doppelter Genauigkeit. Diese Typen sind
wie die unten beschriebenen @code{FLOAT} und @code{DOUBLE}-Typen.
@code{FLOAT(X)} hat denselben Wertebereich wie die entsprechenden
@code{FLOAT}- und @code{DOUBLE}-Typen, jedoch ist die Anzeigebreite und die
Anzahl der Dezimalstellen undefiniert.

In MySQL-Version 3.23 ist das ein echter Fließkommawert. In früheren
MySQL-Versionen hat @code{FLOAT(genauigkeit)} immer 2 Dezimalstellen.

Beachten Sie, dass bei der Benutzung von @code{FLOAT} unerwartete Probleme
auftreten können, weil alle Berechnungen in MySQL mit doppelter Genauigkeit
durchgeführt werden. @xref{No matching rows}.

@cindex ODBC-Kompatibilität
@cindex Kompatibilität, mit ODBC
Diese Syntax steht wegen der ODBC-Kompatibilität zur Verfügung.

@tindex FLOAT
@tindex FLOAT(M,D)
@item FLOAT[(M,D)] [ZEROFILL]

Eine kleine Fließkommazahl (einfacher Genauigkeit). Kann nicht
vorzeichenlos sein. Der Wertebereich umfasst @code{@w{-3.402823466E+38}}
bis @code{@w{-1.175494351E-38}}, @code{0} und @code{@w{1.175494351E-38}}
bis @code{3.402823466E+38}. M ist die Anzeigebreite und D ist die Anzahl
von Dezimalstellen. @code{FLOAT} ohne Argument oder mit einem Argument <=
24 steht für eine Fließkommazahl einfacher Genauigkeit.

@tindex DOUBLE
@tindex FLOAT(genauigkeit)
@item DOUBLE[(M,D)] [ZEROFILL]

Eine normal große Fließkommazahl (doppelter Genauigkeit). Kann nicht
vorzeichenlos sein. Der Wertebereich umfasst
@code{@w{-1.7976931348623157E+308}} bis
@code{@w{-2.2250738585072014E-308}}, @code{0} und
@code{2.2250738585072014E-308} bis @code{1.7976931348623157E+308}. M ist
die Anzeigebreite und D ist die Anzahl von Dezimalstellen. @code{DOUBLE}
ohne Argument oder @code{FLOAT(X)} mit 25 <= X <= 53 steht für eine
Fließkommazahl doppelter Genauigkeit.

@tindex DOUBLE PRECISION
@tindex REAL
@item DOUBLE PRECISION[(M,D)] [ZEROFILL]
@itemx REAL[(M,D)] [ZEROFILL]

Synonyme für @code{DOUBLE}.

@tindex DECIMAL
@item DECIMAL[(M[,D])] [ZEROFILL]

Eine unkomprimierte Fließkommazahl. Kann nicht vorzeichenlos sein. Verhält
sich wie eine @code{CHAR}-Spalte: ``Unkomprimiert'' bedeutet, dass die Zahl
als Zeichenkette gespeichert wird, wobei ein Zeichen für jede Ziffer des
Wertes steht. Der Dezimalpunkt und, bei negativen Zahlen, das
@samp{-}-Zeichen, werden in M nicht mitgezählt (aber hierfür wird Platz
reserviert). Wenn @code{D} 0 ist, haben Werte keinen Dezimalpunkt oder
Bruchteil. Der maximale Wertebereich von @code{DECIMAL}-Werte ist derselbe
wie für @code{DOUBLE}, aber der tatsächliche Wertebereich einer gegebenen
@code{DECIMAL}-Spalte kann durch die Auswahl von @code{M} und @code{D}
eingeschränkt sein.

Wenn @code{D} weggelassen wird, wird es auf 0 gesetzt. Wenn @code{M}
ausgelassen wird, wird es auf 10 gesetzt.

Beachten Sie, dass in MySQL-Version 3.22 das @code{M}-Argument den Platz
für das Vorzeichen und den Dezimalpunkt beinhaltete!

@tindex NUMERIC
@item NUMERIC(M,D) [ZEROFILL]

Synonym für @code{DECIMAL}.

@tindex DATE
@item DATE

Ein Datum. Der unterstützte Wertebereich ist @code{'1000-01-01'} bis
@code{'9999-12-31'}. MySQL zeigt @code{DATE}-Werte im
@code{'YYYY-MM-DD'}-Format an, gestattet jedoch, @code{DATE}-Spalten Werte
entweder als Zeichenketten oder als Zahlen zuzuweisen. @xref{DATETIME}.

@tindex DATETIME
@item DATETIME

Eine Datums-/Zeit-Kombination. Der unterstützte Wertebereich ist
@code{'1000-01-01 00:00:00'} bis @code{'9999-12-31 23:59:59'}. MySQL zeigt
@code{DATETIME}-Werte im @code{'YYYY-MM-DD HH:MM:SS'}-Format an, gestattet
jedoch, @code{DATETIME}-Spalten Werte entweder als Zeichenketten oder als
Zahlen zuzuweisen.
@xref{DATETIME}.

@tindex TIMESTAMP
@item TIMESTAMP[(M)]

Ein Zeitstempel. Der Wertebereich ist @code{'1970-01-01 00:00:00'} bis
irgendwann im Jahr @code{2037}. MySQL zeigt @code{TIMESTAMP}-Werte im
@code{YYYYMMDDHHMMSS}-, @code{YYMMDDHHMMSS}-, @code{YYYYMMDD}- oder
@code{YYMMDD}-Format an, abhängig davon, ob @code{M} @code{14} (oder
fehlend), @code{12}, @code{8} oder @code{6} ist, gestattet aber, dass Sie
@code{TIMESTAMP}-Spalten Werte entweder als Zeichenketten oder als Zahlen
zuweisen. Eine @code{TIMESTAMP}-Spalte ist nützlich, um Datum und Zeit
einer @code{INSERT}- oder @code{UPDATE}-Operation zu speichern, weil sie
automatisch auf das Datum und die Zeit der jüngsten Operation gesetzt wird,
wenn Sie nicht selbst einen Wert zuweisen. Sie können sie auch auf das
aktuelle Datum und die aktuelle Zeit setzen, indem Sie einen
@code{NULL}-Wert zuweisen. @xref{Date and time types}.

Ein @code{TIMESTAMP} wird immer mit 4 Bytes gespeichert. Das
@code{M}-Argument betrifft nur die Anzeige der @code{TIMESTAMP}-Spalte.

Beachten Sie, dass @code{TIMESTAMP(X)}-Spalten, bei denen X 8 oder 14 ist,
als Zahlen interpretiert werden, während andere @code{TIMESTAMP(X)}-Spalten
als Zeichenketten interpretiert werden. Das soll lediglich sicherstellen,
dass Sie Tabellen mit diesen Typen verlässlich dumpen und wiederherstellen
können! @xref{DATETIME}.

@tindex TIME
@item TIME

Ein Zeit-Typ. Der Wertebereich ist @code{'-838:59:59'} bis
@code{'838:59:59'}. MySQL zeigt @code{TIME}-Werte im
@code{'HH:MM:SS'}-Format an, gestattet aber, @code{TIME}-Spalten Werte
entweder als Zeichenketten oder als Zahlen zuweisen. @xref{TIME}.

@tindex YEAR
@item YEAR[(2|4)]

Ein Jahr in 2- oder 4-Ziffernformat (Vorgabe ist 4-Ziffern). Die zulässigen
Werte reichen von @code{1901} bis @code{2155} sowie @code{0000} im
4-Ziffern-Jahresformat, und von 1970 bis 2069 beim 2-Ziffernformat (70 bis
69). MySQL zeigt @code{YEAR}-Werte im @code{YYYY}-Format an, gestattet
aber, @code{YEAR}-Spalten Werte entweder als Zeichenketten oder als Zahlen
zuweisen. (Der @code{YEAR}-Typ ist neu seit MySQL-Version 3.22.).
@xref{YEAR}.

@tindex NATIONAL CHAR
@tindex NCHAR
@tindex CHAR
@tindex CHARACTER
@item [NATIONAL] CHAR(M) [BINARY]

Eine Zeichenkette fester Länge, die beim Speichern rechts stets mit
Leerzeichen bis zur angegebenen Länge aufgefüllt wird. Der Wertebereich von
@code{M} ist 1 bis 255 Zeichen. Leerzeichen am Ende werden beim Abruf des
Wertes entfernt. @code{CHAR}-Werte werden nach dem vorgabemäßigen
Zeichensatz ohne Berücksichtigung der Groß-/Kleinschreibung sortiert und
verglichen, es sei denn, dass Schlüsselwort @code{BINARY} wird angegeben.

@code{NATIONAL CHAR} (Kurzform @code{NCHAR}) ist die Art, wie ANSI-SQL bei
einer CHAR-Spalte festlegt, dass der vorgabemäßige Zeichensatz verwendet
werden soll. Das ist der Vorgabewert in MySQL.

@code{CHAR} ist eine Abkürzung für @code{CHARACTER}.

MySQL erlaubt das Anlegen einer Spalte des Typs @code{CHAR(0)}. Das ist
hauptsächlich nützlich, wenn Sie mit alten Applikationen kompatibel sein
müssen, die auf die Existenz einer Spalte vertrauen, den Wert aber nicht
tatsächlich benutzen. Es ist ebenfalls nett, um eine Spalte anzulegen, die
nur 2 Werte annehmen kann: Eine @code{CHAR(0)}, die nicht als @code{NOT
NULL} definiert ist, belegt nur 1 Bit und kann 2 Werte annehmen:
@code{NULL} oder @code{""}. @xref{CHAR}.

@tindex CHARACTER VARYING
@tindex CHAR VARYING
@tindex VARCHAR
@item [NATIONAL] VARCHAR(M) [BINARY]

Eine Zeichenkette variabler Länge. @strong{HINWEIS:} Leerzeichen am Ende
werden bei der Speicherung des Wertes entfernt (das unterscheidet den Typ
von der ANSI-SQL-Spezifikation). Der Wertebereich von @code{M} ist 1 bis
255 Zeichen. @code{VARCHAR}-Werte werden nach dem vorgabemäßigen
Zeichensatz ohne Berücksichtigung der Groß-/Kleinschreibung sortiert und
verglichen, es sei denn, dass Schlüsselwort @code{BINARY} wird angegeben.
@xref{Silent column changes}.

@code{VARCHAR} ist eine Abkürzung für @code{CHARACTER VARYING}.
@xref{CHAR}.

@tindex TINYBLOB
@tindex TINYTEXT
@item TINYBLOB
@itemx TINYTEXT

Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von 255
(2^8 - 1) Zeichen. @xref{Silent column changes}. @xref{BLOB}.

@tindex BLOB
@tindex TEXT
@item BLOB
@itemx TEXT

Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von
65535 (2^16 - 1) Zeichen. @xref{Silent column changes}. @xref{BLOB}.

@tindex MEDIUMBLOB
@tindex MEDIUMTEXT
@item MEDIUMBLOB
@itemx MEDIUMTEXT

Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von
16777215 (2^24 - 1) Zeichen. @xref{Silent column changes}.
@xref{BLOB}.

@tindex LONGBLOB
@tindex LONGTEXT
@item LONGBLOB
@itemx LONGTEXT

Eine @code{BLOB}- oder @code{TEXT}-Spalte mit einer maximalen Länge von
4294967295 (2^32 - 1) Zeichen. @xref{Silent column changes}.
Beachten Sie, dass Sie nicht den gesamten Wertebereich dieses Typs benutzen
können, weil das Client-Server-Protokoll und MyISAM-Tabellen momentan eine
Beschränkungen auf 16 MB pro Kommunikationspaket / Tabellenzeile haben.
@xref{BLOB}.

@tindex ENUM
@item ENUM('wert1','wert2',...)

An Aufzählung. Ein Zeichenkettenobjekt, das nur einen Wert haben kann, der
aus den Auflistungswerten @code{'wert1'}, @code{'wert2'}, @code{...},
@code{NULL} oder dem speziellen @code{""}-Fehlerwert ausgewählt wird. Eine
@code{ENUM} kann maximal 65535 unterschiedliche Werte haben. @xref{ENUM}.

@tindex SET
@item SET('wert1','wert2',...)

Eine Reihe. Ein Zeichenkettenobjekt, das 0 oder mehr Werte haben kann, von
denen jeder aus den Auflistungswerten @code{'wert1'}, @code{'wert2'},
@code{...} ausgewählt werden muss. Eine @code{SET} kann maximal 64 Elemente
haben. @xref{SET}.
@end table



@menu
* Numeric types::               
* Date and time types::         
* String types::                
* Choosing types::              
* Other-vendor column types::   
* Storage requirements::        
@end menu

@node Numeric types, Date and time types, Column types, Column types
@c German node Numerische Typen
@subsection Numerische Typen

MySQL unterstützt alle numerischen Typen von ANSI/ISO-SQL92. Diese Typen
beinhalten die exakten numerischen Datentypen (@code{NUMERIC},
@code{DECIMAL}, @code{INTEGER} und @code{SMALLINT}) sowie die
näherungsweisen numerischen Datentypen (@code{FLOAT}, @code{REAL} und
@code{DOUBLE PRECISION}). Das Schlüsselwort @code{INT} ist ein Synonym für
@code{INTEGER} und das Schlüsselwort @code{DEC} ist ein Synonym für
@code{DECIMAL}.

Die @code{NUMERIC}- und @code{DECIMAL}-Typen sind in MySQL als derselbe Typ
implementiert, wie es vom SQL92-Standard zugelassen ist. Sie werden für
Werte benutzt, bei denen es wichtig ist, die exakte Genauigkeit zu
bewahren, zum Beispiel bei monetären Daten. Wenn Sie eine Spalte mit einem
dieser Typen deklarieren, können Genauigkeit und Bereich festgelegt werden
(und werden das üblicherweise auch). Beispiel:

@example
    gehalt DECIMAL(9,2)
@end example

In diesem Beispiel repräsentiert @code{9} (@code{genauigkeit}) die Anzahl
signifikanter Dezimalziffern, die für Werte gespeichert werden, und
@code{2} (@code{bereich}) repräsentiert die Anzahl von Ziffern, die nach
dem Dezimalpunkt gespeichert werden. In diesem Fall liegt der Wertebereich,
der in der @code{gehalt}-Spalte gespeichert werden kann, deswegen zwischen
@code{-9999999.99} und @code{9999999.99}. 
(MySQL kann tatsächlich Zahlen bis zu @code{9999999.99} in dieser Spalte
speichern, weil er nicht das Vorzeichen für positive Zahlen speichern
muss).

In ANSI/ISO-SQL92 ist die Syntax @code{DECIMAL(p)} äquivalent zu
@code{DECIMAL(p,0)}. Gleichermaßen ist die Syntax @code{DECIMAL}
äquivalent zu @code{DECIMAL(p,0)}, wobei es der Implementation überlassen
bleibt, den Wert von @code{p} festzulegen. MySQL unterstützt momentan keine
dieser abweichenden Formen der @code{DECIMAL}- / @code{NUMERIC}-Datentypen.
Das ist im Allgemeinen kein ernstes Problem, weil der hauptsächliche Nutzen
dieser Typen darin liegt, sowohl Genauigkeit als auch Bereich explizit
steuern zu können.

@code{DECIMAL}- und @code{NUMERIC}-Werte sind als Zeichenketten gespeichert
statt als Fließkommazahlen, um die dezimale Genauigkeit dieser Werte zu
bewahren. Ein Zeichen wird benutzt für jede Ziffer des Werts, den
Dezimalpunkt (wenn @code{bereich} > 0) und das @samp{-}-Zeichen (für
negative Zahlen). Wenn @code{bereich} 0 ist, enthalten @code{DECIMAL}- und
@code{NUMERIC}-Werte weder Dezimalpunkt noch Bruchteil.

Der maximale Wertebereich von @code{DECIMAL}- und @code{NUMERIC}-Werten ist
derselbe wie für @code{DOUBLE}, aber der tatsächliche Wertebereich einer
gegebenen @code{DECIMAL}- oder @code{NUMERIC}-Spalte kann durch
@code{genauigkeit} oder @code{bereich} für eine gegebene Spalte beschränkt
werden. Wenn einer solchen Spalte ein Wert mit mehr Ziffern nach dem
Dezimalpunkt zugewiesen wird, als durch @code{bereich} zugelassen, wird der
Wert auf diesen @code{bereich} gerundet. Wenn einer @code{DECIMAL}- oder
@code{NUMERIC}-Spalte ein Wert zugewiesen wird, dessen Größe den
Wertebereich überschreitet, der von der festgelegten (oder vorgabemäßigen)
@code{genauigkeit} und @code{bereich} festgelegt wird, speichert MySQL den
Wert des entsprechenden Endpunkts des Wertebereichs.

Als Erweiterung zum ANSI/ISO-SQL92-Standard unterstützt MySQL auch die
Ganzzahltypen @code{TINYINT}, @code{MEDIUMINT} und @code{BIGINT}, wie oben
aufgelistet. Ein andere Erweiterung wird von MySQL unterstützt, um optional
die Anzeigebreite eines Ganzzahlwerts in Klammern festzulegen, die auf das
Basis-Schlüsselwort des Typs folgen (zum Beispiel @code{INT(4)}). Die
optionale Breitenspezifizierung wird benutzt, um die Anzeige von Werten,
deren Breite geringer ist als für die Spalte festgelegt, linksseitig mit
Leerzeichen aufzufüllen. Das begrenzt allerdings nicht den Wertebereich,
der in der Spalte gespeichert werden kann, noch die Anzahl von Ziffern, die
bei Werten angezeigt werden, die die angegebene Breite für die Spalte
überschreiten. In Verbindung mit dem optionalen Erweiterungsattribut
@code{ZEROFILL} wird - statt vorgabemäßig mit Leerzeichen - mit Nullen
aufgefüllt. Bei einer Spalte zum Beispiel, die als @code{INT(5) ZEROFILL}
deklariert wurde, wird @code{4} als @code{00004} dargestellt. Beachten Sie,
dass Werte in einer Ganzzahlspalte, die größer sind als die Anzeigebreite,
Probleme bei der Erzeugung temporärer Tabellen für einige komplizierte
Joins durch MySQL auftreten können, weil MySQL in diesen Fällen darauf
vertraut, dass die Daten in die Original-Spaltenbreite passten.

Alle Ganzzahl-Typen können ein optionales (Nicht-Standard-) Attribut
@code{UNSIGNED} haben. Vorzeichenlose Werte können dafür benutzt werden,
nur positive Zahlen in einer Spalte zuzulassen, wenn Sie eine Wertebereich
brauchen, der etwas größer ausfällt.

Der @code{FLOAT}-Typ wird benutzt, um näherungsweise numerische Datentypen
zu repräsentieren. Der ANSI/ISO-SQL92-Standard erlaubt eine optionale
Festlegung der Genauigkeit (aber nicht den Wertebereich des Exponenten) in
Bits, gefolgt vom Schlüsselwort @code{FLOAT} in Klammern. Die
MySQL-Implementation unterstützt ebenfalls diese optionale
Genauigkeitsfestlegung. Wenn das Schlüsselwort @code{FLOAT} für einen
Spaltentyp ohne Genauigkeitsfestlegung benutzt wird, benutzt MySQL 4 Bytes,
um die Werte zu speichern. Eine abweichende Syntax wird ebenfalls
unterstützt, wobei zwei Zahlen in Klammern dem @code{FLOAT}-Schlüsselwort
folgen. Mit dieser Option legt die erste Zahl wie gehabt den Speicherbedarf
für den Wert in Bytes fest, und die zweite Zahl legt die Anzahl von Ziffern
fest, die nach dem Dezimalpunkt gespeichert und angezeigt werden sollen
(wie bei @code{DECIMAL} und @code{NUMERIC}). Wenn MySQL in einer solchen
Spalte einen Wert mit mehr Dezimalziffern nach dem Dezimalpunkt speichern
soll als für die Spalte festgelegt, wird der Wert beim Speichern gerundet,
um die zusätzlichen Ziffern zu entfernen.

Die @code{REAL}- und @code{DOUBLE PRECISION}-Typen akzeptieren keine
Genauigkeitsfestlegungen. Als Erweiterung zum ANSI/ISO-SQL92-Standard
erkennt MySQL @code{DOUBLE} als ein Synonym für den @code{DOUBLE
PRECISION}-Typ. Im Gegensatz zur Anforderung des Standard, dass die
Genauigkeit für @code{REAL} kleiner sein muss als die für @code{DOUBLE
PRECISION}, implementiert MySQL beide als 8-Byte-Fließkommawerte doppelter
Genauigkeit (wenn er nicht im ``ANSI-Modus'' läuft). Für maximale
Portabilität sollte Code, der die Speicherung näherungsweiser numerischer
Daten erfordert, @code{FLOAT} oder @code{DOUBLE PRECISION} ohne Festlegung
der Genauigkeit oder Anzahl von Dezimalstellen benutzen.

Wenn ein Wert in einer numerischen Spalte gespeichert werden soll, der
ausserhalb des erlaubten Wertebereichs des Spaltentyps ist, schneidet MySQL
den Wert auf den entsprechenden Endpunkt des Wertebereichs ab und speichert
statt dessen diesen Wert.

Der Wertebereich einer @code{INT}-Spalte ist zum Beispiel
@code{-2147483648} bis @code{2147483647}. Wenn Sie versuchen,
@code{-9999999999} in eine @code{INT}-Spalte einzufügen, wird der Wert auf
den unteren Endpunkt des Bereichs abgeschnitten, und es wird
@code{-2147483648} gespeichert. Gleichermaßen wird beim Einfügen in eine
solche Spalte nicht @code{9999999999}, sondern @code{2147483647}
gespeichert.

Wenn die @code{INT}-Spalte @code{UNSIGNED} ist, ist die Größe des
Wertebereichs dieselbe, aber ihre Endpunkte verschieben sich zu @code{0}
und @code{4294967295}. Wenn Sie versuchen, @code{-9999999999} bzw.
@code{9999999999} zu speichern, werden die in der Spalte gespeicherten
Werte statt dessen zu @code{0} bzw. @code{4294967296}.

Umwandlungen, die aufgrund von Abschneiden geschehen, werden als
``Warnungen'' bei @code{ALTER TABLE}, @code{LOAD DATA INFILE},
@code{UPDATE} und in mehrzeiligen @code{INSERT}-Statements berichtet.


@node Date and time types, String types, Numeric types, Column types
@c German node Datums- und Zeit-Typen
@subsection Datums- und Zeit-Typen

@cindex Typen, Datum und Zeit
@cindex Datums- und Zeit-Typen



Die Datums- und Zeit-Typen sind @code{DATETIME}, @code{DATE},
@code{TIMESTAMP}, @code{TIME} und @code{YEAR}. Jeder dieser Typen hat einen
zulässigen Wertebereich sowie einen ``0''-Wert, der benutzt wird, wenn Sie
einen wirklich unzulässigen Wert speichern. Beachten Sie, dass MySQL es
zuläßt, dass Sie bestimmte 'nicht ganz' zulässige Datumswerte speichern,
zum Beispiel @code{1999-11-31}. Der Grund hierfür ist, dass wir meinen,
dass es in der Verantwortung der Applikation liegt, Datumsüberprüfungen
vorzunehmen, und nicht beim SQL-Server. Um Datumsprüfungen 'schnell' zu
machen, überprüft MySQL nur, dass der Monat im Bereich 0 bis 12 liegt und
der Tag im Bereich 0 bis 31. Diese Bereiche sind deshalb so definiert, weil
es MySQL zuläßt, dass Sie in einer @code{DATE}- oder
@code{DATETIME}-Spalte Datumsangaben speichern, bei denen der Tag oder
Monat-Tag 0 sind. Das ist extrem nützlich für Applikationen, die einen
Geburtstag speichern müssen, dessen exaktes Datum unbekannt ist. In diesem
Fall können Sie einfach Datumsangaben wie @code{1999-00-00} oder
@code{1999-01-00} speichern. (Sie können nicht erwarten, von Funktionen wie
@code{DATE_SUB()} oder @code{DATE_ADD} für solche Datumsangaben korrekte
Werte zu erhalten.)

Einige allgemeine Überlegungen, die man im Kopf behalten sollte, wenn man
mit Datums- und Zeit-Typen arbeitet:

@itemize @bullet
@item
MySQL ruft Werte für einen gegebenen Datums- oder Zeit-Typ in einem
Standard-Format ab, versucht aber, eine Vielzahl von Formaten zu
interpretieren, die Sie bereit stellen (wenn Sie zum Beispiel einen Wert
angeben, der zugewiesen oder mit einem Datums- oder Zeit-Typ verglichen
werden soll). Dennoch werden nur die in den folgenden Abschnitten
beschriebenen Formate unterstützt. Es wird davon ausgegangen, dass Sie
zulässige Werte bereitstellen; und es können unvorhersehbare Ergebnisse
zustande kommen, wenn Sie Werte in anderen Formaten angeben.

@item
Obwohl MySQL versucht, Werte in verschiedenen Formaten zu interpretieren,
erwartet er immer, dass der Jahresanteil von Datumswerten ganz links steht.
Datumsangaben müssen in der Reihenfolge Jahr - Monat - Tag gemacht werden
(zum Beispiel @code{'98-09-04'}) statt in der Reihenfolge Monat - Tag -
Jahr oder Tag - Monat - Jahr, die anderswo häufig gebraucht werden (zum
Beispiel @code{'09-04-98'}, @code{'04-09-98'}).

@item
MySQL wandelt einen Datums- oder Zeitwert automatisch in eine Zahl um, wenn
der Wert in einem numerischen Zusammenhang benutzt wird, und umgekehrt.

@item
Wenn MySQL auf einen Datums- oder Zeitwert trifft, der ausserhalb des
Wertebereichs oder in sonstiger Weise für den Typ nicht zulässig ist (siehe
Anfang dieses Abschnitts), wird der Wert zum ``0''-Wert dieses Typs
umgewandelt. (Die Ausnahme ist, dass @code{TIME}-Werte ausserhalb des
Wertebereichs auf den entsprechenden Endpunkt des @code{TIME}-Wertebereichs
abgeschnitten werden.) Die unten stehende Tabelle zeigt das Format des
``0''-Werts für jeden Typ:

@multitable @columnfractions .3 .7
@item @strong{Spaltentyp} @tab @strong{``0''-Wert}
@item @code{DATETIME}      @tab @code{'0000-00-00 00:00:00'}
@item @code{DATE}          @tab @code{'0000-00-00'}
@item @code{TIMESTAMP}     @tab @code{00000000000000} (Länge abhängig von der Anzeigebreite)
@item @code{TIME}          @tab @code{'00:00:00'}
@item @code{YEAR}          @tab @code{0000}
@end multitable

@item
Die ``0''-Werte sind speziell, aber Sie können diese explizit speichern
oder auf sie verweisen, indem Sie die in der Tabelle dargestellten Werte
benutzen. Sie können das auch mit den Werten @code{'0'} oder @code{0}
machen, die leichter zu schreiben sind.

@item
``0''-Datums- oder -Zeitwerte, die über @strong{MyODBC} benutzt werden,
werden in @strong{MyODBC}-Version 2.50.12 und höher automatisch in
@code{NULL} umgewandelt, weil ODBC solche Werte nicht handhaben kann.
@end itemize


@menu
* Y2K issues::                  
* DATETIME::                    
* TIME::                        
* YEAR::                        
@end menu

@node Y2K issues, DATETIME, Date and time types, Date and time types
@c German node Jahr 2000
@subsubsection Jahr-2000-Probleme und Datumstypen

@cindex Jahr-2000-Probleme
@cindex Datumstypen, Jahr-2000-Probleme

MySQL selbst ist Jahr-2000-konform (Jahr-2000-sicher,
@pxref{Year 2000 compliance}), aber Eingabewerte, die an MySQL
übergeben werden, sind das möglicherweise nicht. Jede Eingabe von
Jahreswerten mit 2 Ziffern ist mehrdeutig, weil das Jahrhundert unbekannt
ist. Solche Werte müssen in 4-stellige Form umgedeutet werden, weil MySQL
Jahre intern mit 4 Ziffern speichert.

Bei @code{DATETIME}-, @code{DATE}-, @code{TIMESTAMP}- und @code{YEAR}-Typen
interpretiert MySQL Datumsangaben mit mehrdeutigen Jahreswerten nach
folgenden Regeln:

@itemize @bullet
@item
Jahreswerte im Bereich @code{00 bis 69} werden in @code{2000 bis 2069}
umgewandelt.

@item
Jahreswerte im Bereich @code{70 bis 99} werden in @code{1970 bis 1999}
umgewandelt.
@end itemize

Denken Sie daran, dass diese Regeln nur eine vernünftige Schätzung dessen
bedeuten, was die Daten tatsächlich darstellen sollen. Wenn die von MySQL
benutzten Heuristiken keine korrekten Werte ergeben, müssen Sie eindeutige
Eingaben in Form 4-stelliger Jahreswerte bereit stellen.

@code{ORDER BY} sortiert 2-stellige @code{YEAR/DATE/DATETIME}-Typen
korrekt.

Beachten Sie, dass einige Funktionen wie @code{MIN()} und @code{MAX()} ein
@code{TIMESTAMP / DATE} in eine Zahl umwandeln. Das heißt, dass ein
Zeitstempel mit einer 2-stelligen Jahresangabe bei diesen Funktionen nicht
korrekt funktioniert. Das kann in diesem Fall dadurch behoben werden, dass
der @code{TIMESTAMP / DATE} in ein 4-stelliges Jahresformat umgewandelt
wird, oder etwas wie @code{MIN(DATE_ADD(zeitstempel,INTERVAL 0 DAYS))}
benutzt wird.


@node DATETIME, TIME, Y2K issues, Date and time types
@c German node DATETIME
@subsubsection Die @code{DATETIME}-, @code{DATE}- und @code{TIMESTAMP}-Typen

@tindex DATETIME
@tindex DATE
@tindex TIMESTAMP

Die @code{DATETIME}-, @code{DATE}- und @code{TIMESTAMP}-Typen sind
verwandt. Dieser Abschnitt beschreibt ihre Charakteristiken, wo sie sich
ähnlich sind und wo sie sich unterscheiden.

Der @code{DATETIME}-Typ wird benutzt, wenn Sie Werte brauchen, die sowohl
Datums- als auch Zeitinformationen beinhalten. MySQL ruft
@code{DATETIME}-Werte ab und zeigt sie an im @code{'YYYY-MM-DD
HH:MM:SS'}-Format. Der unterstützte Wertebereich ist @code{'1000-01-01
00:00:00'} bis @code{'9999-12-31 23:59:59'}. (``Unterstützt'' heißt, dass
frühere Werte zwar funktionieren können, dass es aber keine Garantie dafür
gibt.)

Der @code{DATE}-Typ wird benutzt, wenn Sie nur einen Datumswert brauchen,
ohne Zeitanteil. MySQL ruft @code{DATE}-Werte ab und zeigt sie an im
@code{'YYYY-MM-DD'}-Format. Der unterstützte Wertebereich ist
@code{'1000-01-01'} bis @code{'9999-12-31'}.

Der @code{TIMESTAMP}-Typ ist ein Typ, den Sie dafür benutzen können, um
@code{INSERT}- oder @code{UPDATE}-Operationen mit dem aktuellen Datum und
der aktuellen Zeit zu stempeln. Wenn Sie mehrfache @code{TIMESTAMP}-Spalten
haben, wird nur die erste automatisch aktualisiert.

Die automatische Aktualisierung der @code{TIMESTAMP}-Spalte geschieht unter
einer der folgenden Bedingungen:

@itemize @bullet
@item
Die Spalte wird in einem @code{INSERT}- oder @code{LOAD DATA
INFILE}-Statement nicht explizit angegeben.
@item
Die Spalte wird in einem @code{UPDATE}-Statement nicht explizit angegeben,
aber ein anderer Spaltenwert ändert sich. (Beachten Sie, dass ein
@code{UPDATE}, das eine Spalte auf einen Wert setzt, den diese bereits hat,
nicht dazu führt, dass die @code{TIMESTAMP}-Spalte aktualisiert wird, weil
MySQL das Aktualisieren in einem solchen Fall auf Effizienzgründen
ignoriert.)
@item
Wenn Sie die @code{TIMESTAMP}-Spalte explizit auf @code{NULL} setzen.
@end itemize

@code{TIMESTAMP}-Spalten abgesehen von der ersten können ebenfalls auf das
aktuelle Datum und die aktuelle Zeit gesetzt werden. Setzen Sie die Spalte
einfach auf @code{NULL} oder auf @code{NOW()}.

Sie können jede @code{TIMESTAMP}-Spalte auf einen Wert setzen, der vom
aktuellen Datum und der aktuellen Zeit abweicht, indem Sie sie explizit auf
den gewünschten Wert setzen. Das gilt sogar für die erste
@code{TIMESTAMP}-Spalte. Sie können diese Eigenschaft benutzen, wenn Sie
einen @code{TIMESTAMP} auf das aktuelle Datum und die aktuelle Zeit setzen
wollen, wenn Sie eine Zeile erzeugen, nicht aber, wenn die Zeile später
aktualisiert wird:

@itemize @bullet
@item
Lassen Sie MySQL die Spalte setzen, wenn die Zeile erzeugt wird. Das
initialisiert sie auf das aktuelle Datum und die aktuelle Zeit.

@item
Wenn Sie nachfolgende Aktualisierungen anderer Spalten in der Zeile
durchführen, setzen Sie die @code{TIMESTAMP}-Spalte explizit auf ihren
aktuellen Wert.
@end itemize

Auf der anderen Seite finden Sie vielleicht mindestens so einfach, eine
@code{DATETIME}-Spalte zu benutzen, die Sie auf @code{NOW()}
initialisieren, wenn die Zeile erzeugt wird, und die Sie bei nachfolgenden
Aktualisierungen nicht anfassen.

@code{TIMESTAMP}-Werte haben einen Wertebereich von 1970 bis irgendwann im
Jahr 2037, bei einer Auflösung von einer Sekunde. Werte werden als Zahlen
angezeigt.

Das Format, in dem MySQL @code{TIMESTAMP}-Werte abruft und anzeigt, hängt
von der Anzeigebreite ab, wie in der obigen Tabelle dargestellt. Das
`volle' @code{TIMESTAMP}-Format ist 14 Ziffern, aber
@code{TIMESTAMP}-Spalten können mit kürzeren Anzeigebreiten angelegt
werden:

@multitable @columnfractions .3 .7
@item @strong{Spaltentyp}  @tab @strong{Anzeigeformat}
@item @code{TIMESTAMP(14)}  @tab @code{YYYYMMDDHHMMSS}
@item @code{TIMESTAMP(12)}  @tab @code{YYMMDDHHMMSS}
@item @code{TIMESTAMP(10)}  @tab @code{YYMMDDHHMM}
@item @code{TIMESTAMP(8)}   @tab @code{YYYYMMDD}
@item @code{TIMESTAMP(6)}   @tab @code{YYMMDD}
@item @code{TIMESTAMP(4)}   @tab @code{YYMM}
@item @code{TIMESTAMP(2)}   @tab @code{YY}
@end multitable

Alle @code{TIMESTAMP}-Spalten haben dieselbe Speichergröße, unabhängig von
der Anzeigebreite. Die gebräuchlichsten Anzeigebreiten sind 6, 8, 12 und
14. Sie können zur Zeit der Tabellenerzeugung beliebige Anzeigebreiten
festlegen, aber Werte von 0 oder größer als 14 werden auf 14 gesetzt.
Ungerade Werte im Bereich von 1 bis 13 werden auf die nächst höhere gerade
Zahl gesetzt.

Sie können @code{DATETIME}-, @code{DATE}- und @code{TIMESTAMP}-Werte mit
folgenden Formaten festlegen:

@itemize @bullet
@item
Als eine Zeichenkette im @code{'YYYY-MM-DD HH:MM:SS'}- oder @code{'YY-MM-DD
HH:MM:SS'}-Format. Eine ``entspannte'' Syntax ist zugelassen - jedes
Satzzeichen kann als Begrenzer zwischen Datumsanteilen oder Zeitanteilen
verwendet werden. Beispielsweise sind @code{'98-12-31 11:30:45'},
@code{'98.12.31 11+30+45'}, @code{'98/12/31 11*30*45'} und
@code{'98@@12@@31 11^30^45'} äquivalent.

@item
Als eine Zeichenkette im @code{'YYYY-MM-DD'}- oder
@code{'YY-MM-DD'}-Format. Auch hier ist eine ``entspannte'' Syntax
zugelassen. Beispielsweise sind @code{'98-12-31'}, @code{'98.12.31'},
@code{'98/12/31'} und @code{'98@@12@@31'} äquivalent.

@item
Als eine Zeichenkette ohne Begrenzer im @code{'YYYYMMDDHHMMSS'}- oder
@code{'YYMMDDHHMMSS'}-Format, vorausgesetzt, die Zeichenkette ergibt als
Datum einen Sinn. @code{'19970523091528'} und @code{'970523091528'}
beispielsweise werden als @code{'1997-05-23 09:15:28'} interpretiert, aber
@code{'971122129015'} ist unzulässig (es hat einen Minutenanteil, der
keinen Sinn ergibt) und wird in @code{'0000-00-00 00:00:00'} umgewandelt.

@item
Als eine Zeichenkette ohne Begrenzer im @code{'YYYYMMDD'}- oder
@code{'YYMMDD'}-Format, vorausgesetzt, die Zeichenkette ergibt als Datum
einen Sinn. @code{'19970523'} und @code{'970523'} werden als
@code{'1997-05-23'} interpretiert, aber @code{'971332'} ist unzulässig (es
hat einen Monatsanteil und einen Tagesanteil, der keinen Sinn ergibt) und
wird in @code{'0000-00-00'} umgewandelt.

@item
Als eine Zahl im @code{YYYYMMDDHHMMSS}- oder @code{YYMMDDHHMMSS}-Format,
vorausgesetzt, die Zahl ergibt als Datum einen Sinn. @code{19830905132800}
und @code{830905132800} zum Beispiel werden als @code{'1983-09-05
13:28:00'} interpretiert.

@item
Als eine Zahl im @code{YYYYMMDD}- oder @code{YYMMDD}-Format, vorausgesetzt,
die Zahl ergibt als Datum einen Sinn. @code{19830905} und @code{830905} zum
Beispiel werden als @code{'1983-09-05'} interpretiert.

@item
Als Ergebnis einer Funktion, die einen Wert zurückgibt, der in einem
@code{DATETIME}-, @code{DATE}- oder @code{TIMESTAMP}-Zusammenhang einen
Sinn ergibt, wie @code{NOW()} oder @code{CURRENT_DATE}.
@end itemize

Unzulässige @code{DATETIME}-, @code{DATE}- oder @code{TIMESTAMP}-Werte
werden in den ``0''-Wert des jeweiligen Typs umgewandelt (@code{'0000-00-00
00:00:00'}, @code{'0000-00-00'} oder @code{00000000000000}).

Bei Werten, die als Zeichenketten angegeben werden, die Begrenzer für
Datumsanteile enthalten, ist es nicht notwendig, zwei Ziffern für Monats-
oder Tageswerte anzugeben, die weniger als @code{10} sind.
@code{'1979-6-9'} ist dasselbe wie @code{'1979-06-09'}. Gleichermaßen ist
es bei Zeichenketten, die Begrenzer für Zeitanteile enthalten, nicht
notwendig, zwei Ziffern für Stunden-, Monats- oder Sekundenwerte anzugeben,
die weniger als @code{10} sind. @code{'1979-10-30 1:2:3'} ist dasselbe wie
@code{'1979-10-30 01:02:03'}.

Werte, die als Zahlen angegeben sind, sollten 6, 8, 12 oder 14 Ziffern lang
sein. Wenn die Zahl 8 oder 14 Ziffern lang ist, wird angenommen, dass sie
im @code{YYYYMMDD}- oder @code{YYYYMMDDHHMMSS}-Format ist und dass das Jahr
durch die ersten 4 Ziffern angegeben wird. Wenn die Zahl 6 oder 12 Ziffern
lang ist, wird angenommen, dass sie im @code{YYMMDD}- oder
@code{YYMMDDHHMMSS}-Format ist und dass das Jahr durch die ersten 2 Ziffern
angegeben wird. Zahlen, die nicht diesen Längen entsprechen, werden
interpretiert, als ob sie mit führenden Nullen auf die nächst mögliche
Länge gebracht worden wären.

@cindex nicht begrenzte Zeichenketten
@cindex Zeichenketten, non-delimited
Werte, die als nicht begrenzte Zeichenketten angegeben werden, werden
interpretiert, indem ihre Länge als gegeben angenommen wird. Wenn die
Zeichenkette 8 oder 14 Zeichen lang ist, wird angenommen, dass das Jahr
durch die ersten 4 Zeichen angegeben wird. Ansonsten wird angenommen, dass
das Jahr durch die ersten 2 Zeichen angegeben wird. Die Zeichenkette wird
von links nach rechts interpretiert, um die Jahres-, Monats-, Tages-,
Stunden- und Sekundenwerte zu finden, für so viele Anteile, wie in der
Zeichenkette vorkommen. Das bedeutet, dass Sie keine Zeichenketten benutzen
sollten, die weniger als 6 Zeichen haben. Wenn Sie zum Beispiel
@code{'9903'} angeben, in der Annahme, dass das März 1999 darstellt, werden
Sie feststellen, dass MySQL einen ``0''-Datumswert in Ihre Tabelle einfügt.
Das liegt daran, dass die Jahres- und Monatswerte @code{99} und @code{03}
sind, aber der Tagesanteil fehlt (0), so dass der Wert kein zulässiges
Datum darstellt.

@code{TIMESTAMP}-Spalten speichern zulässige Werte mit der vollen
Genauigkeit, mit der der Wert angegeben wurde, unabhängig von der
Anzeigebreite. Das hat mehrere Auswirkungen:

@itemize @bullet
@item
Geben Sie immer Jahr, Monat und Tag an, selbst wenn Ihre Spaltentypen
@code{TIMESTAMP(4)} oder @code{TIMESTAMP(2)} sind. Ansonsten wäre der Wert
kein zulässiges Datum und @code{0} würde gespeichert werden.

@item
Wenn Sie @code{ALTER TABLE} benutzen, um eine enge @code{TIMESTAMP}-Spalte
breiter zu machen, werden Informationen angezeigt, die vorher ``versteckt''
waren.

@item
Gleichermaßen führt das Verengen einer @code{TIMESTAMP}-Spalte nicht dazu,
dass Informationen verloren gehen, ausser in dem Sinn, dass weniger
Informationen dargestellt werden, wenn die Werte angezeigt werden.

@item
Obwohl @code{TIMESTAMP}-Werte mit voller Genauigkeit gespeichert werden,
ist die einzige Funktion, die direkt mit dem zugrunde liegenden
gespeicherten Wert arbeitet, @code{UNIX_TIMESTAMP()}. Alle anderen
Funktionen arbeiten mit dem formatierten, abgerufenen Wert. Das bedeutet,
Sie können keine Funktionen wie @code{HOUR()} oder @code{SECOND()}
benutzen, wenn nicht auch der relevante Teil des @code{TIMESTAMP}-Werts im
formatierten Werte enthalten ist. Wenn zum Beispiel der @code{HH}-Teil
einer @code{TIMESTAMP}-Spalte nicht angezeigt wird, wenn die Anzeigebreite
nicht mindestens 10 beträgt, wird der Versuch, @code{HOUR()} auf kürzere
@code{TIMESTAMP}-Werte anzuwenden, unsinnige Ergebnisse erzeugen.
@end itemize

Bis zu einem gewissen Grad können Sie einem Objekt eines Datumstyp Werte
eines anderen Datumstyps zuweisen. Jedoch kann eine Änderung des Wertes
oder ein Informationsverlust eintreten:

@itemize @bullet
@item
Wenn Sie einem @code{DATETIME}- oder @code{TIMESTAMP}-Objekt einen
@code{DATE}-Wert zuweisen, wird der Zeitanteil im Ergebniswert auf
@code{'00:00:00'} gesetzt, weil der @code{DATE}-Wert keine
Zeitinformationen enthält.

@item
Wenn Sie einem @code{DATE}-Objekt einen @code{DATETIME}- oder
@code{TIMESTAMP}-Wert zuweisen, wird der Zeitanteil des Ergebniswerts
gelöscht, weil der @code{DATE}-Typ keine Zeitinformationen speichert.

@item
Denken Sie daran, dass @code{DATETIME}-, @code{DATE}- und
@code{TIMESTAMP}-Werte zwar in denselben Formaten angegeben werden können,
dass die Typen jedoch nicht alle denselben Wertebereich haben.
@code{TIMESTAMP}-Werte zum Beispiel können nicht früher als @code{1970}
oder später als @code{2037} sein. Das bedeutet, dass ein Datum wie
@code{'1968-01-01'}, was als @code{DATETIME} oder @code{DATE}-Wert zulässig
wäre, kein gültiger @code{TIMESTAMP}-Wert ist und in @code{0} umgewandelt
wird, wenn er einem solchen Objekt zugewiesen wird.
@end itemize

@cindex Probleme, Datumswerte
@cindex Datumswerte, Probleme
Seien Sie auf der Hut vor Fallstricken, wenn Sie Datumswerte angeben:

@itemize @bullet
@item
Das entspannte Format läßt Werte als Zeichenketten zu, die täuschen
können. Ein Wert wie @code{'10:11:12'} zum Beispiel sieht wegen des
@samp{:}-Begrenzers wie ein Zeitwert aus, wird er aber in einem
Datums-Zusammenhang benutzt, wird er als das Datum @code{'2010-11-12'}
interpretiert. Der Wert @code{'10:45:15'} wird in @code{'0000-00-00'}
umgewandelt, weil @code{'45'} kein zulässiger Monat ist.

@item
Jahreswerte, die als zwei Ziffern angegeben werden, sind mehrdeutig, weil
das Jahrhundert unbekannt ist. 
unknown.  MySQL interpretiert 2-stellige Jahreswerte nach folgenden Regeln:

@itemize @minus
@item
Jahreswerte im Bereich @code{00 bis 69} werden in @code{2000 bis 2069}
umgewandelt.

@item
Jahreswerte im Bereich @code{70 bis 99} werden in @code{1970 bis 1999}
umgewandelt.
@end itemize
@end itemize


@node TIME, YEAR, DATETIME, Date and time types
@c German node TIME
@subsubsection Der @code{TIME}-Typ

@tindex TIME

MySQL ruft @code{TIME}-Werte ab und zeigt sie an im
@code{'HH:MM:SS'}-Format (oder @code{'HHH:MM:SS'}-Format für große
Stundenwerte). @code{TIME}-Werte rangieren von @code{'-838:59:59'} bis
@code{'838:59:59'}. Der Grund dafür, dass der Stundenanteil so Groß sein
kann, liegt darin, dass der @code{TIME}-Typ nicht nur benutzt werden kann,
um die Tageszeit zu repräsentieren (wobei die Stunden weniger als 24 sein
müssen), sondern auch abgelaufene Zeit oder ein Zeitintervall zwischen zwei
Ereignissen (was viel größer als 24 Stunden oder sogar negativ sein kann).

Sie können @code{TIME}-Werte in einer Vielzahl von Formaten angeben:

@itemize @bullet
@item
Als eine Zeichenkette im @code{'D HH:MM:SS.bruchteil'}-Format. (Beachten
Sie, dass MySQL bislang nicht den Bruchteil für die TIME-Spalte speichert.)
Man kann auch folgende ``entspannte'' Syntax benutzen:

@code{HH:MM:SS.bruchteil}, @code{HH:MM:SS}, @code{HH:MM}, @code{D HH:MM:SS},
@code{D HH:MM}, @code{D HH} oder @code{SS}. Hierbei ist @code{D} Tage
zwischen 0 und 33.

@item
Als eine Zeichenkette ohne Begrenzer im @code{'HHMMSS'}-Format,
vorausgesetzt, dass diese als Zeitangabe einen Sinn ergibt. @code{'101112'}
zum Beispiel wird als @code{'10:11:12'} interpretiert, aber @code{'109712'}
ist unzulässig (es hat einen Minutenanteil, der keinen Sinn ergibt) und
wird in @code{'00:00:00'} umgewandelt.

@item
Als eine Zahl im @code{HHMMSS}-Format, vorausgesetzt, dass diese als
Zeitangabe einen Sinn ergibt. @code{101112} zum Beispiel wird als
@code{'10:11:12'} interpretiert. Folgende alternativen Formate werden
ebenfalls verstanden: @code{SS}, @code{MMSS}, @code{HHMMSS},
@code{HHMMSS.bruchteil}. Beachten Sie, dass MySQL bislang noch nicht den
Bruchteil speichert.

@item
Als Ergebnis einer Funktion, die einen Wert zurück gibt, der in einem
@code{TIME}-Zusammenhang akzeptabel ist, wie @code{CURRENT_TIME}.
@end itemize

Bei @code{TIME}-Werten, die als Zeichenketten angegeben sind, die einen
Begrenzer für den Zeitanteil beinhalten, ist es nicht notwendig, zwei
Ziffern für Stunden-, Minuten- oder Sekunden-Werte anzugeben, die weniger
als @code{10} sind. @code{'8:3:2'} ist dasselbe wie @code{'08:03:02'}.

Seien Sie vorsichtig damit, einer @code{TIME}-Spalte ``kurze''
@code{TIME}-Werte zuzuweisen. Ohne Semikolon interpretiert MySQL Werte
unter der Annahme, dass die am weitesten rechts stehenden Ziffern Sekunden
repräsentieren. (MySQL interpretiert @code{TIME}-Werte als vergangene Zeit
statt als Tageszeit.) Sie könnten zum Beispiel denken, dass @code{'1112'}
und @code{1112} @code{'11:12:00'} bedeuten (12 Minuten nach 11 Uhr), aber
MySQL interpretiert sie als @code{'00:11:12'} (11 Minuten, 12 Sekunden).
Gleichermaßen wird @code{'12'} und @code{12} als @code{'00:00:12'}
interpretiert. @code{TIME}-Werte mit Semikolon werden statt dessen immer
als Tageszeit interpretiert. Das heißt, @code{'11:12'} bedeutet
@code{'11:12:00'}, nicht @code{'00:11:12'}.

Werte, die ausserhalb des @code{TIME}-Wertebereichs liegen, ansonsten aber
zulässig sind, werden auf den entsprechenden Endpunkt des Wertebereichs
abgeschnitten. @code{'-850:00:00'} bzw. @code{'850:00:00'} werden in
@code{'-838:59:59'} bzw. @code{'838:59:59'} umgewandelt.

Unzulässige @code{TIME}-Werte werden in @code{'00:00:00'} umgewandelt.
Beachten Sie, dass es keine Möglichkeit gibt zu unterscheiden, wenn ein
Wert von @code{'00:00:00'} in einer Tabelle gespeichert ist, ob dieser
originär als @code{'00:00:00'} eingegeben wurde oder ob es ein unzulässiger
Wert war, weil @code{'00:00:00'} selbst ein zulässiger @code{TIME}-Wert
ist.


@node YEAR,  , TIME, Date and time types
@c German node YEAR
@subsubsection Der @code{YEAR}-Typ

@tindex YEAR

Der @code{YEAR}-Typ ist ein 1-Byte-Typ, der für die Darstellung von Jahren
benutzt wird.

MySQL ruft @code{YEAR}-Werte ab und speichert sie im @code{YYYY}-Format.
Der Wertebereich ist @code{1901} bis @code{2155}.

Sie können @code{YEAR}-Werte in einer Vielzahl von Formaten angeben:

@itemize @bullet
@item
Als vierstellige Zeichenkette im Wertebereich von @code{'1901'} bis
@code{'2155'}.

@item
Als vierstellige Zahl im Wertebereich von @code{1901} bis @code{2155}.

@item
Als zweistellige Zeichenkette im Wertebereich von @code{'00'} bis
@code{'99'}. Werte in den Bereichen von @code{'00'} bis @code{'69'} und
@code{'70'} bis @code{'99'} werden in @code{YEAR}-Werte in den Bereichen
von @code{2000} bis @code{2069} und @code{1970} bis @code{1999}
umgewandelt.

@item
Als zweistellige Zahl im Wertebereich von @code{1} bis @code{99}. Werte in
den Bereichen von @code{1} bis @code{69} und @code{70} bis @code{99} werden
in @code{YEAR}-Werte in den Bereichen von @code{2001} bis @code{2069} und
@code{1970} bis @code{1999} umgewandelt. Beachten Sie, dass der
Wertebereich für zweistellige Zahlen sich geringfügig vom Wertebereich für
zweistellige Zeichenketten unterscheidet, weil Sie 0 nicht direkt als Zahl
eingeben können und sie dann als @code{2000} interpretiert wird. Sie
@emph{müssen} sie als Zeichenkette @code{'0'} oder @code{'00'} angeben,
oder sie wird als @code{0000} interpretiert.

@item
Als Ergebnis einer Funktion, die einen Wert zurück gibt, der in einem
@code{YEAR}-Zusammenhang akzeptabel ist, wie @code{NOW()}.
@end itemize

Unzulässige @code{YEAR}-Werte werden in @code{0000} umgewandelt.


@node String types, Choosing types, Date and time types, Column types
@c German node Zeichenketten-Typen
@subsection Zeichenketten-Typen

@cindex Typen, Zeichenketten
@cindex Zeichenketten-Typen

@tindex CHAR
@tindex VARCHAR



Die Zeichenketten-Typen sind @code{CHAR}, @code{VARCHAR}, @code{BLOB},
@code{TEXT}, @code{ENUM} und @code{SET}.  Dieser Abschnitt beschreibt, wie
diese Typen funktionieren, ihren Speicherbedarf und wie sie in Anfragen
benutzt werden.


@menu
* CHAR::                        
* BLOB::                        
* ENUM::                        
* SET::                         
@end menu

@node CHAR, BLOB, String types, String types
@c German node CHAR
@subsubsection Die @code{CHAR}- und @code{VARCHAR}-Typen

Die @code{CHAR}- und @code{VARCHAR}-Typen sind ähnlich, unterscheiden sich
aber in der Art, wie sie gespeichert und abgerufen werden.

Die Länge einer @code{CHAR}-Spalte wird auf die Länge festgelegt, die Sie
bei der Erzeugung der Tabelle angeben. Die Länge kann zwischen 1 und 255
variieren. (Ab MySQL-Version 3.23 kann die Länge zwischen 0 und 255
liegen.) Wenn @code{CHAR}-Werte gespeichert werden, werden sie am rechten
Ende bis zur festgelegten Länge mit Leerzeichen aufgefüllt. Wenn
@code{CHAR}-Werte abgerufen werden, werden die Leerzeichen am Ende
entfernt.

Werte in @code{VARCHAR}-Spalten sind Zeichenketten variabler Länge. Sie
können eine @code{VARCHAR}-Spalte mit jeder Länge zwischen 1 und 255
deklarieren, genau wie für @code{CHAR}-Spalten. Im Gegensatz zu @code{CHAR}
werden @code{VARCHAR}-Werte jedoch nur mit so vielen Zeichen wie nötig
gespeichert, plus 1 Byte, um die Länge zu speichern. Die Werte werden nicht
aufgefüllt; statt dessen werden Leerzeichen am Ende beim Speichern
entfernt. (Diese Entfernung von Leerzeichen weicht von der
ANSI-SQL-Spezifikation ab.)

Wenn Sie einer @code{CHAR}- oder @code{VARCHAR}-Spalte einen Wert zuweisen,
der die maximale Spaltenlänge überschreitet, wird der Wert so zurecht
geschnitten, das er passt.

Die unten stehende Tabelle stellt die Unterschiede zwischen den beiden
Spaltentypen dar, indem das Ergebnis der Speicherung unterschiedlicher
Zeichenkettenwerte in @code{CHAR(4)}- und @code{VARCHAR(4)}-Spalten gezeigt
wird:

@c Need to use @(space) to make sure second Spaltenwerte retain spacing
@c in output für Tabelle below.

@multitable @columnfractions .2 .15 .2 .2 .25
@item @strong{Wert}  @tab @code{CHAR(4)}     @tab @strong{Speicherbedarf} @tab @code{VARCHAR(4)} @tab @strong{Speicherbedarf}
@item @code{''}       @tab @code{'@ @ @ @ '} @tab 4 Bytes @tab @code{''} @tab 1 Byte
@item @code{'ab'}     @tab @code{'ab@ @ '}   @tab 4 Bytes @tab @code{'ab'} @tab 3 Bytes
@item @code{'abcd'}   @tab @code{'abcd'}     @tab 4 Bytes @tab @code{'abcd'} @tab 5 Bytes
@item @code{'abcdefgh'} @tab @code{'abcd'}     @tab 4 Bytes @tab @code{'abcd'} @tab 5 Bytes
@end multitable

Die Werte, die aus den @code{CHAR(4)}- und @code{VARCHAR(4)}-Spalten
abgerufen werden, sind in jedem Fall gleich, weil Leerzeichen am Ende von
@code{CHAR}-Spalten beim Abruf entfernt werden.

Werte in @code{CHAR}- und @code{VARCHAR}-Spalten werden unabhängig von der
Groß-/Kleinschreibung sortiert und verglichen, es sei denn, beim Erzeugen
der Tabelle wurde das @code{BINARY}-Attribut festgelegt. Das
@code{BINARY}-Attribut bedeutet, dass Spaltenwerte abhängig von der
Groß-/Kleinschreibung in Übereinstimmung mit der ASCII-Reihenfolge der
Maschine sortiert und verglichen werden, auf der der MySQL-Server läuft.
@code{BINARY} beeinflusst nicht, wie die Spalte gespeichert oder abgerufen
wird.

Das @code{BINARY}-Attribut ist 'klebrig', das heißt, dass der gesamte
Ausdruck als ein @code{BINARY}-Wert verglichen wird, sobald eine
@code{BINARY}-Spalte im Ausdruck benutzt wird.

MySQL ändert eventuell 'still' den Typ von @code{CHAR}- oder
@code{VARCHAR}-Spalten bei der Tabellenerzeugung.
@c German FIX unwrapped @xref
@xref{Silent column changes}.


@node BLOB, ENUM, CHAR, String types
@c German node BLOB
@subsubsection Die @code{BLOB}- und @code{TEXT}-Typen

@tindex BLOB
@tindex TEXT

Ein @code{BLOB} ist großes Binärobjekt (Binary Large OBject), das eine
variable Menge von Daten enthalten kann. Die vier @code{BLOB}-Typen
@code{TINYBLOB}, @code{BLOB}, @code{MEDIUMBLOB} und @code{LONGBLOB}
unterscheiden sich nur hinsichtlich der maximalen Länge der Werte, die sie
aufnehmen können.
@xref{Storage requirements}.

Die vier @code{TEXT}-Typen @code{TINYTEXT}, @code{TEXT},
@code{MEDIUMTEXT} und @code{LONGTEXT} entsprechen den vier
@code{BLOB}-Typen und haben dieselben maximalen Längen und denselben
Speicherbedarf. Der einzige Unterschied zwischen @code{BLOB}- und
@code{TEXT}-Typen ist, dass beim Sortieren und Vergleichen bei
@code{BLOB}-Werten Groß-/Kleinschreibung berücksichtigt wird, bei
@code{TEXT}-Werten dagegen nicht. Mit anderen Worten ist ein @code{TEXT}
ein @code{BLOB} ohne Berücksichtigung der Groß-/Kleinschreibung.

Wenn Sie einer @code{BLOB}- oder @code{TEXT}-Spalte einen Wert zuweisen,
der die maximale Länge des Spaltentyps überschreitet, wird der Wert so
zurecht geschnitten, dass er passt.

In fast jeder Hinsicht können Sie eine @code{TEXT}-Spalte als eine
@code{VARCHAR}-Spalte betrachten, die so Groß sein kann, wie Sie wollen.
Gleichermaßen können Sie eine @code{BLOB}-Spalte als eine @code{VARCHAR
BINARY}-Spalte betrachten. Die Unterschiede sind:

@itemize @bullet
@item
Seit MySQL-Version 3.23.2 können Sie Indexe auf @code{BLOB}- und
@code{TEXT}-Spalten anlegen. Ältere Versionen von MySQL unterstützten das
nicht.

@item
Leerzeichen am Ende werden beim Speichern von @code{BLOB}- und
@code{TEXT}-Spalten nicht wie bei @code{VARCHAR}-Spalten entfernt.

@item
@cindex Vorgabewerte, @code{BLOB}- und @code{TEXT}-Spalten
@cindex @code{BLOB}-Spalten, Vorgabewerte
@cindex @code{TEXT}-Spalten, Vorgabewerte
@code{BLOB}- und @code{TEXT}-Spalten können keine @code{DEFAULT}-Werte
haben.
@end itemize

@strong{MyODBC} definiert @code{BLOB}-Werte als @code{LONGVARBINARY} und
@code{TEXT}-Werte als @code{LONGVARCHAR}.

Weil @code{BLOB}- und @code{TEXT}-Werte extrem lang sein können, treffen
Sie bei der Benutzung eventuell auf Beschränkungen:

@itemize @bullet
@item
Wenn Sie @code{GROUP BY} oder @code{ORDER BY} für @code{BLOB}- oder
@code{TEXT}-Spalten benutzen wollen, müssen Sie den Spaltenwert in ein
Objekt fester Länge umwandeln. Standardmäßig wird das mit der
@code{SUBSTRING}-Funktion gemacht. Beispiel:

@example
mysql> select kommentar from tabelle,substring(kommentar,20) as substr
       ORDER BY substr;
@end example

Wenn Sie das nicht tun, werden nur die ersten @code{max_sort_length} Bytes
der Spalte beim Sortieren benutzt. Der Vorgabewert von
@code{max_sort_length} ist 1024; dieser Wert kann mit der @code{-O}-Option
geändert werden, wenn der @code{mysqld}-Server gestartet wird. Sie können
auf einen Ausdruck, der @code{BLOB}- oder @code{TEXT}-Werte enthält,
gruppieren, indem Sie die Spaltenposition angeben oder ein Alias benutzen:

@example
mysql> select id,substring(blob_spalte,1,100) from tabelle
           GROUP BY 2;
mysql> select id,substring(blob_spalte,1,100) as b from tabelle
           GROUP BY b;
@end example

@item
Die maximale Größe eines @code{BLOB}- oder @code{TEXT}-Objekts wird durch
seinen Typ festgelegt, aber der größte Wert, den Sie tatsächlich zwischen
Client und Server übertragen können, wird von der Menge verfügbaren
Arbeitsspeichers und der Größe des Kommunikationspuffers festgelegt. Sie
können die Nachrichtenpuffergröße ändern, müssen das aber auf beiden
Seiten, also beim Client und beim Server, tun. @xref{Server parameters}.
@end itemize

Beachten Sie, dass intern jeder @code{BLOB}- oder @code{TEXT}-Wert durch
ein separat zugewiesenes Objekt dargestellt wird. Das steht im Gegensatz zu
allen anderen Spaltentypen, für die Speicherplatz einmal pro Spalte
zugewiesen wird, wenn die Tabelle geöffnet wird.


@node ENUM, SET, BLOB, String types
@c German node ENUM
@subsubsection Der @code{ENUM}-Typ

@tindex ENUM

Ein @code{ENUM} ist ein Zeichenketten-Objekt, dessen Wert normalerweise aus
einer Liste zulässiger Werte ausgesucht wird, die explizit bei der
Spaltenspezifizierung bei der Tabellenerzeugung aufgezählt werden.

Der Wert kann unter bestimmten Umständen auch die leere Zeichenkette
(@code{""}) oder @code{NULL} sein:

@itemize @bullet
@item
Wenn Sie in eine @code{ENUM} einen ungültigen Wert einfügen (das ist eine
Zeichenkette, die es in der Auflistung zugelassener Werte nicht gibt), wird
statt dessen die leere Zeichenkette als spezieller Fehlerwert eingefügt.
Diese Zeichenkette kann von einer 'normalen' leeren Zeichenkette dadurch
unterschieden werden, dass diese Zeichenkette den numerischen Wert 0 hat.
Mehr dazu später.

@item
Wenn ein @code{ENUM} als @code{NULL} deklariert ist, ist @code{NULL}
ebenfalls ein zulässiger Wert für die Spalte und der Vorgabewert ist
@code{NULL}. Wenn ein @code{ENUM} als @code{NOT NULL} deklariert ist, ist
der Vorgabewert das erste Element der Auflistung erlaubter Werte.
@end itemize

Jeder Aufzählungswert hat einen Index:

@itemize @bullet
@item
Werte der Auflistung zulässiger Elemente in der Spaltenspezifikation fangen
mit 1 an.

@item
Der Indexwert des Fehlerwerts leere Zeichenkette ist 0. Folglich können Sie
folgendes @code{SELECT}-Statement benutzen, um Zeilen zu finden, denen
unzulässige @code{ENUM}-Werte zugewiesen wurden:

@example
mysql> SELECT * FROM tabelle WHERE enum_spalte=0;
@end example

@item
Der Index des @code{NULL}-Werts ist @code{NULL}.
@end itemize

Wenn beispielsweise eine Spalte als @code{ENUM("eins", "zwei", "drei")}
festgelegt wurde, kann sie einen der unten dargestellen Werte besitzen. Der
Index jedes Werts wird auch dargestellt:

@multitable @columnfractions .2 .8
@item @strong{Wert} @tab @strong{Index}
@item @code{NULL}    @tab @code{NULL}
@item @code{""}      @tab 0
@item @code{"eins"}   @tab 1
@item @code{"zwei"}   @tab 2
@item @code{"drei"} @tab 3
@end multitable

Eine Aufzählung kann maximal 65535 Elemente enthalten.

Groß-/Kleinschreibung ist irrelevant, wenn Sie einer @code{ENUM}-Spalte
Werte zuweisen. Jedoch haben Werte, die später aus der Spalte abgerufen
werden, dieselbe Groß-/Kleinschreibung wie die Werte, die für die
Festlegung zulässiger Werte bei der Tabellenerzeugung verwendet wurden.

Wenn Sie eine @code{ENUM} in einem numerischen Zusammenhang benutzen, wird
der Index des Spaltenwerts zurückgegeben. Sie können beispielsweise
numerische Werte aus einer @code{ENUM}-Spalte wie folgt abrufen:

@example
mysql> SELECT enum_spalte+0 FROM tabelle;
@end example

Wenn Sie eine Zahl in eine @code{ENUM} speichern, wird die Zahl als Index
behandelt und der gespeicherte Wert ist das Aufzählungselement mit diesem
Index. (Das funktioniert jedoch nicht bei @code{LOAD DATA}, was alle
Eingaben als Zeichenketten behandelt.)

@code{ENUM}-Werte werden in der Reihenfolge sortiert, wie die
Aufzählungselemente bei der Spaltenspezifizierung eingegeben wurden. (Mit
anderen Worten werden @code{ENUM}-Werte nach ihren Indexzahlen sortiert.)
So wird beispielsweise @code{"a"} vor @code{"b"} einsortiert bei
@code{ENUM("a", "b")}, aber @code{"b"} wird vor @code{"a"} einsortiert bei
@code{ENUM("b", "a")}. Die leere Zeichenkette wird vor nicht leeren
Zeichenketten und @code{NULL}-Werte vor allen anderen Aufzählungswerten
einsortiert.

Wenn Sie alle möglichen Werte einer @code{ENUM}-Spalte erhalten wollen,
benutzen Sie: @code{SHOW COLUMNS FROM tabelle LIKE enum_spalte} und gehen
die @code{ENUM}-Definition in der zweiten Spalte durch.


@node SET,  , ENUM, String types
@c German node SET
@subsubsection Der @code{SET}-Typ

@tindex SET

Ein @code{SET} ist ein Zeichenketten-Objekt, das 0 oder mehr Werte haben
kann, wovon jedes aus einer Auflistung zulässiger Werte stammen muss, die
bei der Tabellenerzeugung festgelegt wurden. @code{SET}-Spaltenwerte, die
aus mehrfachen SET-Elementen bestehen, werden angegeben, indem die Elemente
durch Kommas (@samp{,}) getrennt werden. Daraus ergibt sich, dass
@code{SET}-Elemente selbst keine Kommas enthalten dürfen.

Eine Spalte beispielsweise, die als @code{SET("eins", "zwei") NOT NULL}
festgelegt wurde, kann folgende Werte haben:

@example
""
"eins"
"zwei"
"eins,zwei"
@end example


Eine @code{SET} kann maximal 64 unterschiedliche Elemente besitzen.

MySQL speichert @code{SET}-Werte numerisch, wobei das niedrigste Bit in der
Reihenfolge der gespeicherten Werte dem ersten SET-Element entspricht. Wenn
Sie einen @code{SET}-Wert in einem numerischen Zusammenhang abrufen, hat
der abgerufene Werte Bits gesetzt, die den SET-Elementen, aus denen sich
der Spaltenwert zusammensetzt, entspricht. Beispielsweise können Sie
numerische Werte aus einer @code{SET}-Spalte wie folgt abrufen:

@example
mysql> SELECT set_spalte+0 FROM tabelle;
@end example

Wenn in einer @code{SET}-Spalte eine Zahl gespeichert wird, legen die Bits,
die in der binären Darstellung der Zahl gesetzt sind, die SET-Elemente im
Spaltenwert fest. Angenommen, eine Spalte ist als
@code{SET("a","b","c","d")} festgelegt, dann haben die Elemente folgende
Bitwerte:

@multitable @columnfractions .2 .2 .6
@item @code{SET} @strong{Element} @tab @strong{Dezimalwert} @tab @strong{Binärwert}
@item @code{a} @tab @code{1} @tab @code{0001}
@item @code{b} @tab @code{2} @tab @code{0010}
@item @code{c} @tab @code{4} @tab @code{0100}
@item @code{d} @tab @code{8} @tab @code{1000}
@end multitable

Wenn Sie dieser Spalte einen Wert von @code{9} zuweisen, ist das binär
@code{1001}. Daher werden der erste und der vierte @code{SET}-Wert, die
Elemente @code{"a"} und @code{"d"}, ausgewählt, und der Ergebniswert ist
@code{"a,d"}.

Bei einem Wert, der mehr als ein @code{SET}-Element enthält, spielt es
keine Rolle, in welcher Reihenfolge die Elemente aufgelistet sind, wenn Sie
den Wert einfügen. Es spielt ebenfalls keine Rolle, wie oft ein gegebenes
Element im Wert aufgelistet ist. Wenn der Wert später abgerufen wird,
erscheint jedes Element im Wert einmal, wobei die Elemente in der
Reihenfolge erscheinen, in der sie bei der Tabellenerzeugung festgelegt
wurden. Wenn eine Spalte beispielsweise als @code{SET("a","b","c","d")}
festgelegt ist, erscheinen @code{"a,d"}, @code{"d,a"} und
@code{"d,a,a,d,d"} als @code{"a,d"}, wenn sie abgerufen werden.

@code{SET}-Werte werden numerisch sortiert. @code{NULL}-Werte werden vor
Nicht-@code{NULL}-@code{SET}-Werten einsortiert.

Normalerweise führt man @code{SELECT} auf eine @code{SET}-Spalte mit dem
@code{LIKE}-Operator oder der @code{FIND_IN_SET()}-Funktion aus:

@example
mysql> SELECT * FROM tabelle WHERE set_spalte LIKE '%wert%';
mysql> SELECT * FROM tabelle WHERE FIND_IN_SET('wert',set_spalte)>0;
@end example

Aber auch folgendes funktioniert:

@example
mysql> SELECT * FROM tabelle WHERE set_spalte = 'wert1,wert2';
mysql> SELECT * FROM tabelle WHERE set_spalte & 1;
@end example

Das erste dieser Statements sucht nach einer exakten Übereinstimmung, das
zweite sucht Werte, die das erste SET-Element enthalten.

Wenn Sie alle möglichen Werte einer @code{SET}-Spalte erhalten wollen,
benutzen Sie: @code{SHOW COLUMNS FROM tabelle LIKE set_spalte} und gehen
die @code{SET}-Definition in der zweiten Spalte durch.


@node Choosing types, Other-vendor column types, String types, Column types
@c German node Typen auswählen
@subsection Den richtigen Typ für eine Spalte auswählen

@cindex Typen, Spalten
@cindex Typen auswählen

Um möglichst effizient zu speichern, benutzen Sie in jedem Fall den
präzisesten Typ. Wenn zum Beispiel eine Ganzzahl-Spalte für Werte im
Bereich zwischen @code{1} und @code{99999} benutzt wird, ist
@code{MEDIUMINT UNSIGNED} der beste Typ.

Akkurate Darstellung monetärer Werte ist ein häufiges Problem. In MySQL
sollten Sie den @code{DECIMAL}-Typ benutzen. Dieser wird als Zeichenkette
gepeichert, weshalb kein Genauigkeitsverlust auftreten sollte. Wenn
Genauigkeit nicht allzu wichtig ist, sollte auch der @code{DOUBLE}-Typ
ausreichen.

Um hohe Präzision zu erzielen, können Sie immer auch in einen Festkommawert
umwandeln, der in einer @code{BIGINT} gespeichert wird. Das erlaubt Ihnen,
alle Berechnungen mit Ganzzahlen durchzuführen und die Ergebnisse nur wenn
notwendig in Fließkommawerte zurückzuwandeln.


@node Other-vendor column types, Storage requirements, Choosing types, Column types
@c German node Spaltentypen anderer Hersteller
@subsection Spaltentypen anderer Datenbanken benutzen

@cindex Typen, Portabilität
@cindex Portabilität, Typen
@cindex Spalten, andere Typen

Um es einfacher zu machen, Code zu verwenden, der für SQL-Implementationen
anderer Hersteller geschrieben wurde, ordnet (mappt) MySQL Spaltentypen zu
wie in unten stehender Tabelle dargestellt. Diese Mappings machen es
leichter, Tabellendefinitionen anderer Datenbanken nach MySQL zu
verschieben:

@multitable @columnfractions .4 .6
@item @strong{Typ anderer Hersteller}   @tab @strong{MySQL-Typ}
@item @code{BINARY(NUM)}		@tab @code{CHAR(NUM) BINARY}
@item @code{CHAR VARYING(NUM)}		@tab @code{VARCHAR(NUM)}
@item @code{FLOAT4}			@tab @code{FLOAT}
@item @code{FLOAT8}			@tab @code{DOUBLE}
@item @code{INT1}			@tab @code{TINYINT}
@item @code{INT2}			@tab @code{SMALLINT}
@item @code{INT3}			@tab @code{MEDIUMINT}
@item @code{INT4}			@tab @code{INT}
@item @code{INT8}			@tab @code{BIGINT}
@item @code{LONG VARBINARY}		@tab @code{MEDIUMBLOB}
@item @code{LONG VARCHAR}		@tab @code{MEDIUMTEXT}
@item @code{MIDDLEINT}			@tab @code{MEDIUMINT}
@item @code{VARBINARY(NUM)}		@tab @code{VARCHAR(NUM) BINARY}
@end multitable

Dass Zuordnen (Mapping) von Spaltentypen geschieht bei der Erzeugung der
Tabelle. Wenn Sie eine Tabelle mit Typen erzeugen, die von anderen
Herstellern benutzt werden, und dann ein @code{DESCRIBE tabelle}-Statement
absetzen, zeigt MySQL die Tabellenstruktur mit den äquivalenten MySQL-Typen
an.


@node Storage requirements,  , Other-vendor column types, Column types
@c German node Speicherbedarf
@subsection Speicherbedarf von Spaltentypen

@cindex Speicherbedarf, Spaltentyp
@cindex Spalten, Speicherbedarf

Der Speicherbedarf jedes Spaltentyps, der von MySQL unterstützt wird, ist
unten nach Kategorie sortiert aufgelistet:

@cindex numerische Typen
@cindex Typen, numerische

@subsubheading Speicherbedarf für numerische Typen

@multitable @columnfractions .5 .5
@item @strong{Spaltentyp} @tab @strong{Speicherbedarf}
@item @code{TINYINT}       @tab 1 Byte
@item @code{SMALLINT}      @tab 2 Bytes
@item @code{MEDIUMINT}     @tab 3 Bytes
@item @code{INT}           @tab 4 Bytes
@item @code{INTEGER}       @tab 4 Bytes
@item @code{BIGINT}        @tab 8 Bytes
@item @code{FLOAT(X)}      @tab 4, wenn X <= 24, oder 8, wenn 25 <= X <= 53
@item @code{FLOAT}         @tab 4 Bytes
@item @code{DOUBLE}        @tab 8 Bytes
@item @code{DOUBLE PRECISION} @tab 8 Bytes
@item @code{REAL}         @tab 8 Bytes
@item @code{DECIMAL(M,D)} @tab @code{M+2} Bytes, wenn D > 0, @code{M+1} Bytes, wenn D = 0 (@code{D}+2, wenn @code{M < D})
@item @code{NUMERIC(M,D)} @tab @code{M+2} Bytes, wenn D > 0, @code{M+1} Bytes, wenn D = 0 (@code{D}+2, wenn @code{M < D})
@end multitable

@cindex Datumstypen
@cindex Zeittypen
@cindex Typen, Datum
@cindex Typen, Zeit

@subsubheading Speicherbedarf für Datums- und Zeit-Typen

@multitable @columnfractions .5 .5
@item @strong{Spaltentyp} @tab @strong{Speicherbedarf}
@item @code{DATE}          @tab 3 Bytes
@item @code{DATETIME}      @tab 8 Bytes
@item @code{TIMESTAMP}     @tab 4 Bytes
@item @code{TIME}          @tab 3 Bytes
@item @code{YEAR}          @tab 1 Byte
@end multitable

@subsubheading Speicherbedarf für Zeichenketten-Typen

@multitable @columnfractions .5 .5
@item @strong{Spaltentyp} @tab @strong{Speicherbedarf}
@item @code{CHAR(M)} @tab @code{M} Bytes, @code{1 <= M <= 255}
@item @code{VARCHAR(M)} @tab @code{L}+1 Bytes, wobei @code{L <= M} und
@code{1 <= M <= 255}
@item @code{TINYBLOB}, @code{TINYTEXT} @tab @code{L}+1 Bytes,
wobei @code{L} < 2^8
@item @code{BLOB}, @code{TEXT} @tab @code{L}+2 Bytes,
wobei @code{L} < 2^16
@item @code{MEDIUMBLOB}, @code{MEDIUMTEXT} @tab @code{L}+3 Bytes,
wobei @code{L} < 2^24
@item @code{LONGBLOB}, @code{LONGTEXT} @tab @code{L}+4 Bytes,
wobei @code{L} < 2^32
@item @code{ENUM('wert1','wert2',...)} @tab 1 oder 2 Bytes, abhängig von
der Anzahl der Aufzählungswerte (65535 Werte maximal)
@item @code{SET('wert1','wert2',...)} @tab 1, 2, 3, 4 oder 8 Bytes,
abhängig von der Anzahl von SET-Elementen (64 Elemente maximal)
@end multitable

@cindex @code{BLOB}, Größe
@cindex @code{TEXT}, Größe
@cindex @code{VARCHAR}, Größe
@code{VARCHAR} und die @code{BLOB}- und @code{TEXT}-Typen sind Typen
variabler Länge, bei denen der Speicherbedarf von der tatsächlichen Länge
der Spaltenwerte abhängt (in der vorstehenden Tabelle dargestellt durch
@code{L}) statt von der maximal möglichen Größe des Typs.
@code{VARCHAR(10)} zum Beispiel kann eine Zeichenkette mit einer maximalen
Länge von 10 Zeichen enthalten. Der tatsächliche Speicherbedarf ist die
Länge der Zeichenkette (@code{L}) plus 1 Byte, um die Länge zu speichern.
Bei der Zeichenkette @code{'abcd'} ist @code{L} 4 und der Speicherbedarf 5
Bytes.

Die @code{BLOB}- und @code{TEXT}-Typen benötigen 1, 2, 3 oder 4 Bytes, um
die Länge des Spaltenwerts zu speichern, abhängig von der maximal möglichen
Länge des Typs.  @xref{BLOB}.

Wenn eine Tabelle irgend welche Spaltentypen variabler Länge enthält, ist
das Datensatzformat ebenfalls von variabler Länge. Beachten Sie, dass MySQL
bei der Erzeugung einer Tabelle unter bestimmten Umständen eine Spalte
eines Typs variabler Länge in einen Typ fester Länge umwandelt, und
umgekehrt. @xref{Silent column changes}.

@cindex ENUM, Größe
Die Größe eines @code{ENUM}-Objekts hängt von der Anzahl unterschiedlicher
Aufzählungswerte ab. Bei Aufzählungen mit bis zu 255 möglichen Werten wird
1 Byte benutzt, bei Aufzählungen mit bis zu 65535 Werten 2 Bytes.
@xref{ENUM}.

@cindex SET, Größe
Die Größe eines @code{SET}-Objekts hängt von der Anzahl unterschiedlicher
SET-Elemente ab. Wenn die SET-Größe @code{N} ist, belegt das Objekt
@code{(N+7)/8} Bytes, gerundet auf 1, 2, 3, 4 oder 8 Bytes. Ein @code{SET}
kann maximal 64 Elemente besitzen. @xref{SET}.


@node Functions, Data Manipulation, Column types, Reference
@c German node Funktionen
@section Funktionen für die Benutzung in @code{SELECT}- und @code{WHERE}-Klauseln

@cindex Funktionen für @code{SELECT} und @code{WHERE}-Klauseln

Ein @code{select_ausdruck} oder eine @code{where_definition} in einem
SQL-Statement kann aus jedem beliebigen Ausdruck bestehen, der die unten
beschriebenen Funktionen benutzt.

Ein Ausdruck, der @code{NULL} enthält, erzeugt immer einen
@code{NULL}-Wert, wenn es in der Dokumentation für die Operatoren und
Funktionen, die im Ausdruck vorkommen, nicht anders beschrieben ist.

@strong{HINWEIS:} Zwischen Funktionsname und der folgenden Klammer darf
kein Leerraum stehen. Das hilft dem MySQL-Parser, zwischen
Funktionsaufrufen und Tabellen- oder Spaltenverweisen zu unterscheiden, die
denselben Namen haben wie eine Funktion. Leerzeichen um Argumente herum
sind dagegen zulässig.

Sie können MySQL zwingen, Leerzeichen nach dem Funktionsnamen zu
akzeptieren, indem Sie @code{mysqld} mit @code{--ansi} starten oder
@code{CLIENT_IGNORE_SPACE} bei @code{mysql_connect()}, benutzen, aber in
diesem Fall werden alle Funktionsnamen zu reservierten Wörtern.
@xref{ANSI mode}.

@need 2000

Der Kürze zuliebe sind die Ausgaben des @code{mysql}-Programms in gekürzter
Form dargestellt. Daher wird

@example
mysql> select MOD(29,9);
+-----------+
| mod(29,9) |
+-----------+
|         2 |
+-----------+
1 rows in set (0.00 sec)
@end example

wie folgt dargestellt:

@example
mysql> select MOD(29,9);
        -> 2
@end example



@menu
* Non-typed Operators::         
* String functions::            
* Numeric Functions::           
* Date and time functions::     
* Other Functions::             
* Group by functions::          
@end menu

@node Non-typed Operators, String functions, Functions, Functions
@c German node Nicht typenspezifische Operatoren
@subsection Nicht typenspezifische Operatoren und Funktionen



@menu
* Parentheses::                 
* Comparison Operators::        
* Logical Operators::           
* Control flow functions::      
@end menu

@node Parentheses, Comparison Operators, Non-typed Operators, Non-typed Operators
@c German node Klammer
@subsubsection Klammer

@findex () (Klammern)
@findex Klammern ( und )

@cindex Funktionen, Gruppierungs-
@cindex Gruppierung, Ausdrücke

@example
( ... )
@end example

Benutzen Sie Klammern, um die Reihenfolge der Auswertung in einem Ausdruck
zu erzwingen. Beispiel:

@example
mysql> select 1+2*3;
        -> 7
mysql> select (1+2)*3;
        -> 9
@end example



@node Comparison Operators, Logical Operators, Parentheses, Non-typed Operators
@c German node Vergleichsoperatoren
@subsubsection Vergleichsoperatoren

@findex Vergleichsoperatoren

@cindex Casts
@cindex Typumwandlungen

Vergleichsoperationen ergeben einen Wert von @code{1} (TRUE), @code{0}
(FALSE) oder @code{NULL}. Diese Funktionen funktionieren sowohl bei Zahlen
als auch bei Zeichenketten. Zeichenketten werden bei Bedarf automatisch in
Zahlen und Zahlen in Zeichenketten umgewandelt (wie in Perl oder PHP).

MySQL führt Vergleiche nach folgenden Regeln durch:

@itemize @bullet
@item
Wenn ein oder beide Argumente @code{NULL} sind, ist das Ergebnis des
Vergleichs @code{NULL}, ausser beim @code{<=>} Operator.

@item
Wenn beide Argumente in einer Vergleichsoperation Zeichenketten sind,
werden sie als Zeichenketten verglichen.

@item
Wenn beide Argumente Ganzzahlen sind, werden sie als Ganzzahlen verglichen.

@item
Hexadezimale Werte werden als binäre Zeichenketten behandelt, wenn sie
nicht mit einer Zahl verglichen werden.

@item
@cindex ODBC-Kompatibilität
@cindex Kompatibilität, mit ODBC
Wenn eins der Argumente eine @code{TIMESTAMP}- oder @code{DATETIME}-Spalte
ist und das andere Argument eine Konstante, wird die Konstante in einen
Zeitstempel umgewandelt, bevor der Vergleich durchgeführt wird. Das wird
gemacht, um ODBC-freundlicher zu sein.

@item
In allen anderen Fällen werden die Argumente als Fließkommazahlen
verglichen.
@end itemize

Vorgabemäßig werden Zeichenketten-Vergleiche unabhängig von der verwendeten
Groß-/Kleinschreibung durchgeführt, indem der aktuelle Zeichensatz benutzt
wird (vorgabemäßig ISO-8859-1 Latin1, der auch für englisch exzellent
funktioniert).

Die unten stehenden Beispiele erläutern die Umwandlung von Zeichenketten in
Zahlen für Vergleichsoperationen:

@example
mysql> SELECT 1 > '6x';
         -> 0
mysql> SELECT 7 > '6x';
         -> 1
mysql> SELECT 0 > 'x6';
         -> 0
mysql> SELECT 0 = 'x6';
         -> 1
@end example

@table @code
@findex = (gleich)
@findex gleich (=)
@item =
Gleich:
@example
mysql> select 1 = 0;
        -> 0
mysql> select '0' = 0;
        -> 1
mysql> select '0.0' = 0;
        -> 1
mysql> select '0.01' = 0;
        -> 0
mysql> select '.01' = 0.01;
        -> 1
@end example

@findex <> (ungleich)
@findex ungleich (<>)
@findex != (ungleich)
@findex ungleich (!=)
@item <>
@itemx !=
Ungleich:
@example
mysql> select '.01' <> '0.01';
        -> 1
mysql> select .01 <> '0.01';
        -> 0
mysql> select 'zapp' <> 'zappp';
        -> 1
@end example

@findex <= (kleiner oder gleich)
@findex kleiner oder gleich (<=)
@item <=
Kleiner oder gleich:
@example
mysql> select 0.1 <= 2;
        -> 1
@end example

@findex < (kleiner als)
@findex kleiner als (<)
@item <
Kleiner als:
@example
mysql> select 2 < 2;
        -> 0
@end example

@findex >= (größer oder gleich)
@findex größer oder gleich (>=)
@item >=
Größer oder gleich:
@example
mysql> select 2 >= 2;
        -> 1
@end example

@findex > (größer als)
@findex größer als (>)
@item >
Größer als:
@example
mysql> select 2 > 2;
        -> 0
@end example

@cindex @code{NULL}, testen auf Null
@findex <=> (Gleich)
@item <=>
Null-sicheres gleich:
@example
mysql> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1 1 0
@end example

@cindex @code{NULL}, testen auf Null
@findex IS NULL
@findex IS NOT NULL
@item IS NULL
@itemx IS NOT NULL
Testet, ob eine Wert @code{NULL} ist oder nicht:
@example
mysql> select 1 IS NULL, 0 IS NULL, NULL IS NULL;
        -> 0 0 1
mysql> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
        -> 1 1 0
@end example

@findex BETWEEN ... AND
@item ausdruck BETWEEN min AND max
Wenn @code{ausdruck} größer oder gleich @code{min} ist und @code{ausdruck}
kleiner oder gleich @code{max} ist, gibt @code{BETWEEN} @code{1} zurück,
andernfalls @code{0}. Das ist äquivalent zum Ausdruck @code{(min <=
ausdruck AND ausdruck <= max)}, wenn alle Argumente vom selben Typ sind.
Das erste Argument (@code{ausdruck}) legt fest, wie der Vergleich
durchgeführt wird:

@itemize @bullet
@item
Wenn @code{ausdruck} eine @code{TIMESTAMP}-, @code{DATE}- oder
@code{DATETIME}-Spalte ist, werden @code{MIN()} und @code{MAX()} im selben
Format formatiert als wären sie Konstanten.
@item
Wenn @code{ausdruck} ein Zeichenketten-Ausdruck ohne Berücksichtigung der
Groß-/Kleinschreibung ist, wird ein Zeichenkettenvergleich ohne
Berücksichtigung der Groß-/Kleinschreibung durchgeführt.
@item
Wenn @code{ausdruck} ein Zeichenketten-Ausdruck mit Berücksichtigung der
Groß-/Kleinschreibung ist, wird ein Zeichenkettenvergleich mit
Berücksichtigung der Groß-/Kleinschreibung durchgeführt.
@item
Wenn @code{ausdruck} ist ein Ganzzahl-Ausdruck ist, wird ein
Ganzzahlvergleich durchgeführt.
@item
Ansonsten wird ein Fließkommazahlenvergleich durchgeführt.
@end itemize

@example
mysql> select 1 BETWEEN 2 AND 3;
        -> 0
mysql> select 'b' BETWEEN 'a' AND 'c';
        -> 1
mysql> select 2 BETWEEN 2 AND '3';
        -> 1
mysql> select 2 BETWEEN 2 AND 'x-3';
        -> 0
@end example

@findex IN
@item ausdruck IN (wert,...)
Gibt @code{1} zurück, wenn @code{ausdruck} einen Wert hat, der in der
@code{IN}-Liste enthalten ist, ansonsten @code{0}. Wenn alle Werte
Konstanten sind, werden alle Werte gemäß dem Typ von @code{ausdruck}
ausgewertet und sortiert. Danach wird ein Element mittels binärer Suche
gesucht. Das heißt, dass @code{IN} sehr schnell ist, wenn die
@code{IN}-Werteliste ausschließlich aus Konstanten besteht. Wenn
@code{ausdruck} ein Zeichenketten-Ausdruck mit Berücksichtigung der
Groß-/Kleinschreibung ist, wird der Zeichenkettenvergleich unter
Berücksichtigung der Groß-/Kleinschreibung durchgeführt:

@example
mysql> select 2 IN (0,3,5,'wefwf');
        -> 0
mysql> select 'wefwf' IN (0,3,5,'wefwf');
        -> 1
@end example

@findex NOT IN
@item ausdruck NOT IN (wert,...)
Dasselbe wie @code{NOT (ausdruck IN (wert,...))}.

@findex ISNULL()
@item ISNULL(ausdruck)
Wenn @code{ausdruck} @code{NULL} ist, gibt @code{ISNULL()} @code{1} zurück,
ansonsten @code{0}:
@example
mysql> select ISNULL(1+1);
        -> 0
mysql> select ISNULL(1/0);
        -> 1
@end example

Beachten Sie, dass ein Vergleich von @code{NULL}-Werten mit @code{=} immer
UNWAHR ergibt!

@cindex @code{NULL}, testen auf Null
@findex COALESCE()
@item COALESCE(liste)
Gibt das erste Nicht-@code{NULL}-Element in der Liste zurück:

@example
mysql> select COALESCE(NULL,1);
        -> 1
mysql> select COALESCE(NULL,NULL,NULL);
        -> NULL
@end example

@findex INTERVAL()
@item INTERVAL(N,N1,N2,N3,...)
Gibt @code{0} zurück, wenn @code{N} < @code{N1}, @code{1}, wenn @code{N} <
@code{N2} usw. Alle Argumente werden als Ganzzahlen behandelt. Es ist
erforderlich, dass @code{N1} < @code{N2} < @code{N3} < @code{...} <
@code{Nn} ist, damit diese Funktion korrekt funktioniert. Das liegt daran,
dass eine (sehr schnelle) binäre Suche benutzt wird:

@example
mysql> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
        -> 3
mysql> select INTERVAL(10, 1, 10, 100, 1000);
        -> 2
mysql> select INTERVAL(22, 23, 30, 44, 200);
        -> 0
@end example
@end table

Wenn Sie eine Zeichenkette, die Groß-/Kleinschreibung nicht
berücksichtigt, mit einem der Standard-Operatoren vergleichen (@code{=},
@code{<>}..., aber nicht @code{LIKE}), werden Leerzeichen am Ende
ignoriert:

@example
mysql> select "a" ="A ";
        -> 1
@end example


@node Logical Operators, Control flow functions, Comparison Operators, Non-typed Operators
@c German node Logische Operatoren
@subsubsection Logische Operatoren

@findex Logische Funktionen
@findex Funktionen, logische

Alle logischen Funktionen geben @code{1} (TRUE), @code{0} (FALSE) oder
@code{NULL} (unbekannt, was in den meisten Fällen dasselbe wie FALSE ist)
zurück:

@table @code
@findex NOT, logisch
@findex ! (logisch NOT)
@item NOT
@itemx !
Logisch NOT. Gibt @code{1} zurück, wenn das Argument @code{0} ist,
ansonsten @code{0}.
Ausnahme: @code{NOT NULL} gibt @code{NULL} zurück:
@example
mysql> select NOT 1;
        -> 0
mysql> select NOT NULL;
        -> NULL
mysql> select ! (1+1);
        -> 0
mysql> select ! 1+1;
        -> 1
@end example
Das letzte Beispiel gibt @code{1} zurück, weil der Ausdruck auf dieselbe
Art ausgewertet wird wie @code{(!1)+1}.

@findex OR, logisch
@findex || (logisch OR)
@item OR
@itemx ||
Logisch OR. Gibt @code{1} zurück, wenn eins der Argumente nicht @code{0}
und nicht @code{NULL} ist:
@example
mysql> select 1 || 0;
        -> 1
mysql> select 0 || 0;
        -> 0
mysql> select 1 || NULL;
        -> 1

@end example

@findex AND, logisch
@findex && (logisch AND)
@item AND
@itemx &&
Logisch AND. Gibt @code{0} zurück, wenn eins der Argumente @code{0} oder
@code{NULL} ist, ansonsten @code{1}:
@example
mysql> select 1 && NULL;
        -> 0
mysql> select 1 && 0;
        -> 0
@end example
@end table


@node Control flow functions,  , Logical Operators, Non-typed Operators
@c German node Ablaufsteuerungsfunktionen
@subsubsection Ablaufsteuerungsfunktionen

@findex Ablaufsteuerungsfunktionen
@findex Funktionen, Ablaufsteuerung

@table @code
@cindex @code{NULL}, testen auf Null
@findex IFNULL()
@item IFNULL(ausdruck1,ausdruck2)
Wenn @code{ausdruck1} nicht @code{NULL} ist, gibt @code{IFNULL()}
@code{ausdruck1} zurück, ansonsten @code{ausdruck2}. @code{IFNULL()} gibt
einen numerischen oder einen Zeichenketten-Wert zurück, je nachdem, in
welchem Zusammenhang es benutzt wird:
@example
mysql> select IFNULL(1,0);
        -> 1
mysql> select IFNULL(NULL,10);
        -> 10
mysql> select IFNULL(1/0,10);
        -> 10
mysql> select IFNULL(1/0,'ja');
        -> 'ja'
@end example

@findex NULLIF()
@item NULLIF(ausdruck1,ausdruck2)
Wenn @code{ausdruck1 = ausdruck2} wahr ist, gibt die Funktion @code{NULL}
zurück, ansonsten @code{ausdruck1}. Das ist dasselbe wie @code{CASE WHEN x
= y THEN NULL ELSE x END}:
@example
mysql> select NULLIF(1,1);
        -> NULL
mysql> select NULLIF(1,2);
        -> 1
@end example

Beachten Sie, dass @code{ausdruck1} in MySQL zweimal ausgewertet wird, wenn
die Argumente gleich sind.

@findex IF()
@item IF(ausdruck1,ausdruck2,ausdruck3)
Wenn @code{ausdruck1} TRUE ist (@code{ausdruck1 <> 0} und @code{ausdruck1
<> NULL}), gibt @code{IF()} @code{ausdruck2} zurück, ansonsten
@code{ausdruck3}. @code{IF()} gibt einen numerischen oder einen
Zeichenketten-Wert zurück, je nachdem, in welchem Zusammenhang es benutzt
wird:

@example
mysql> select IF(1>2,2,3);
        -> 3
mysql> select IF(1<2,'ja','nein');
        -> 'ja'
mysql> select IF(strcmp('test','test1'),'nein','ja');
        -> 'nein'
@end example

@code{ausdruck1} wird als Ganzzahlwert ausgewertet, woraus folgt, dass Sie
das Testen auf Fließkomma- oder Zeichenketten-Werte mit einer
Vergleichsoperation durchführen sollten:

@example
mysql> select IF(0.1,1,0);
        -> 0
mysql> select IF(0.1<>0,1,0);
        -> 1
@end example

Im ersten Fall gibt @code{IF(0.1)} @code{0} zurück, weil @code{0.1} in
einen Ganzzahlwert umgewandelt wird, wodurch es auf @code{IF(0)} getestet
wird. Das ist vielleicht nicht das, was Sie erwarten. Im zweiten Fall
testet der Vergleich den Original-Fließkommawert, um zu sehen, ob er nicht
0 ist. Das Ergebnis des Vergleichs wird als Ganzzahl benutzt.

Der vorgabemäßige Rückgabewert von @code{IF()} (der eine Rolle spielen
kann, wenn er in einer temporären Tabelle gespeichert wird), wird in
MySQL-Version 3.23 wie folgt berechnet:

@multitable @columnfractions .55 .45
@item @strong{Ausdruck} @tab @strong{Rückgabewert}
@item ausdruck2 oder ausdruck3 gibt Zeichenkette zurück @tab Zeichenkette
@item ausdruck2 oder ausdruck3 gibt Fließkommawert zurück @tab Fließkommawert
@item ausdruck2 oder ausdruck3 gibt Ganzzahl zurück @tab Ganzzahl
@end multitable

@findex CASE
@item CASE wert WHEN [vergleichs-wert] THEN ergebnis [WHEN [vergleichs-wert] THEN ergebnis ...] [ELSE ergebnis] END
@item CASE WHEN [bedingung] THEN ergebnis [WHEN [bedingung] THEN ergebnis ...] [ELSE ergebnis] END

Die erste Version gibt @code{ergebnis} zurück, wo
@code{wert=vergleichs-wert}. Die zweite Version gibt das Ergebnis für die
erste Bedingung zurück, die WAHR ist. Wenn es keinen übereinstimmenden
Ergebniswert gab, wird das Ergebnis nach @code{ELSE} zurückgegeben. Wenn es
keinen @code{ELSE}-Teil gibt, wird @code{NULL} zurückgegeben:

@example
mysql> SELECT CASE 1 WHEN 1 THEN "eins" WHEN 2 THEN "zwei" ELSE "mehr" END;
       -> "eins"
mysql> SELECT CASE WHEN 1>0 THEN "wahr" ELSE "unwahr" END;
       -> "wahr"
mysql> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
       -> NULL
@end example
@end table

Der Typ des Rückgabewerts (@code{INTEGER}, @code{DOUBLE} oder
@code{STRING}) ist derselbe wie der Typ des ersten zurückgegebenen Werts
(der Ausdruck nach dem ersten @code{THEN}).


@node String functions, Numeric Functions, Non-typed Operators, Functions
@c German node Zeichenketten-Funktionen
@subsection Zeichenketten-Funktionen

@findex Zeichenketten-Funktionen
@findex Funktionen, Zeichenketten

Funktionen für Zeichenkettenwerte geben @code{NULL} zurück, wenn die Länge
des Ergebnisses größer wäre als der
@code{max_allowed_packet}-Serverparameter. @xref{Server parameters}.

Bei Funktionen, die mit Zeichenkettenpositionen arbeiten, wird die erste
Position als 1 gezählt.

@table @code
@findex ASCII()
@item ASCII(zeichenkette)
Gibt den ASCII-Code-Wert des äußersten linken Zeichens der Zeichenkette
@code{zeichenkette} zurück. Gibt @code{0} zurück, wenn @code{zeichenkette}
die leere Zeichenkette ist. Gibt @code{NULL} zurück, wenn
@code{zeichenkette} @code{NULL} ist:

@example
mysql> select ASCII('2');
        -> 50
mysql> select ASCII(2);
        -> 50
mysql> select ASCII('dx');
        -> 100
@end example

Siehe auch @code{ORD()}-Funktion.

@findex ORD()
@item ORD(zeichenkette)
Wenn das äußerste linke Zeichen der Zeichenkette @code{zeichenkette} ein
Multi-Byte-Zeichen ist, gibt diese Funktion den Code des
Multi-Byte-Zeichens zurück, indem der ASCII-Code-Wert des Zeichens in
folgendem Format zurückgegeben wird:
@code{((erstes byte ASCII code)*256+(zweites byte ASCII code))[*256+drittes byte ASCII code...]}.
Wenn das äußerste linke Zeichen kein Multi-Byte-Zeichen ist, wird derselbe
Wert wie bei der @code{ASCII()}-Funktion zurückgegeben:

@example
mysql> select ORD('2');
        -> 50
@end example

@findex CONV()
@item CONV(N,von_basis,zu_basis)
Wandelt Zahlen zwischen verschiedenen Zahlsystemen um. Gibt eine
Zeichenkettendarstellung der Zahl @code{N} zurück, umgewandelt von Basis
@code{von_basis} zu Basis @code{zu_basis}. Gibt @code{NULL} zurück, wenn
irgend ein Argument @code{NULL} ist. Das Argument @code{N} wird als
Ganzzahl interpretiert, kann aber als Ganzzahl oder Zeichenkette angegeben
werden. Die kleinste Basis ist @code{2} und die größte Basis @code{36}.
Wenn @code{zu_basis} eine negative Zahl ist, wird @code{N} als
vorzeichenbehaftete Zahl betrachtet. Ansonsten wird @code{N} als
vorzeichenlos behandelt. @code{CONV} arbeitet mit 64-Bit-Genauigkeit:

@example
mysql> select CONV("a",16,2);
        -> '1010'
mysql> select CONV("6E",18,8);
        -> '172'
mysql> select CONV(-17,10,-18);
        -> '-H'
mysql> select CONV(10+"10"+'10'+0xa,10,10);
        -> '40'
@end example

@findex BIN()
@item BIN(N)
Gibt eine Zeichenkettendarstellung des Binärwerts von @code{N} zurück,
wobei @code{N} eine @code{BIGINT}-Zahl ist. Das ist äquivalent zu
@code{CONV(N,10,2)}. Gibt @code{NULL} zurück, wenn @code{N} @code{NULL}
ist:

@example
mysql> select BIN(12);
        -> '1100'
@end example

@findex OCT()
@item OCT(N)
Gibt eine Zeichenkettendarstellung des Oktalwerts von @code{N} zurück,
wobei @code{N} eine @code{BIGINT}-Zahl ist. Das ist äquivalent zu
@code{CONV(N,10,8)}. Gibt @code{NULL} zurück, wenn @code{N} @code{NULL}
ist:

@example
mysql> select OCT(12);
        -> '14'
@end example

@findex HEX()
@item HEX(N)
Gibt eine Zeichenkettendarstellung des hexadezimalen Werts von @code{N}
zurück, wobei @code{N} eine @code{BIGINT}-Zahl ist. Das ist äquivalent zu
@code{CONV(N,10,16)}. Gibt @code{NULL} zurück, wenn @code{N} @code{NULL}
ist:

@example
mysql> select HEX(255);
        -> 'FF'
@end example

@findex CHAR()
@item CHAR(N,...)
@code{CHAR()} interpretiert die Argumente als Ganzzahlen und gibt eine
Zeichenkette zurück, die aus den Zeichen besteht, die durch die
ASCII-Code-Werte dieser Ganzzahlen gegeben sind. @code{NULL}-Werte werden
übersprungen:

@example
mysql> select CHAR(77,121,83,81,'76');
        -> 'MySQL'
mysql> select CHAR(77,77.3,'77.3');
        -> 'MMM'
@end example

@findex CONCAT()
@item CONCAT(zeichenkette1,zeichenkette2,...)
Gibt die Zeichenkette zurück, die durch die Verkettung der Argumente
entsteht. Gibt @code{NULL} zurück, wenn irgend ein Argument @code{NULL}
ist. Kann mehr als 2 Argumente haben. Ein numerisches Argument wird in die
äquivalente Zeichenkettenform umgewandelt:

@example
mysql> select CONCAT('My', 'S', 'QL');
        -> 'MySQL'
mysql> select CONCAT('My', NULL, 'QL');
        -> NULL
mysql> select CONCAT(14.3);
        -> '14.3'
@end example

@findex CONCAT_WS()
@item CONCAT_WS(trennzeichen, zeichenkette1, zeichenkette2,...)

@code{CONCAT_WS()} steht für CONCAT mit Trennzeichen und ist eine spezielle
Form von @code{CONCAT()}. Das erste Argument ist das Trennzeichen für die
restlichen Argumente. Das Trennzeichen kann eine Zeichenkette sein, so wie
die übrigen Argumente. Wenn das Trennzeichen @code{NULL} ist, ist das
Ergebnis @code{NULL}. Die Funktion überspringt jegliche @code{NULL}s und
leere Zeichenketten nach dem Trennzeichen-Argument. Das Trennzeichen wird
zwischen den zu verknüpfenden Zeichenketten hinzugefügt:

@example
mysql> select CONCAT_WS(",","Vorname","Zweiter Vorname","Nachname");
       -> 'Vorname,Zweiter Vorname,Nachname'
mysql> select CONCAT_WS(",","Vorname",NULL,"Nachname");
       -> 'Vorname,Nachname'
@end example

@findex LENGTH()
@findex OCTET_LENGTH()
@findex CHAR_LENGTH()
@findex CHARACTER_LENGTH()
@item LENGTH(zeichenkette)
@itemx OCTET_LENGTH(zeichenkette)
@itemx CHAR_LENGTH(zeichenkette)
@itemx CHARACTER_LENGTH(zeichenkette)
Gibt die Länge der Zeichenkette @code{zeichenkette} an:

@example
mysql> select LENGTH('text');
        -> 4
mysql> select OCTET_LENGTH('text');
        -> 4
@end example

Beachten Sie, dass bei @code{CHAR_LENGTH()} Multi-Byte-Zeichen nur einmal
gezählt werden.

@findex LOCATE()
@findex POSITION()
@item LOCATE(teilzeichenfolge,zeichenkette)
@itemx POSITION(teilzeichenfolge IN zeichenkette)
Gibt die Position des ersten Auftretens der Teilzeichenfolge
@code{teilzeichenfolge} in der Zeichenkette @code{zeichenkette} an. Gibt
@code{0} zurück, wenn @code{teilzeichenfolge} nicht in @code{zeichenkette}
enthalten ist:

@example
mysql> select LOCATE('bar', 'foobarbar');
        -> 4
mysql> select LOCATE('xbar', 'foobar');
        -> 0
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex LOCATE()
@item LOCATE(teilzeichenfolge,zeichenkette,position)
Gibt die Position des ersten Auftretens der Teilzeichenfolge
@code{teilzeichenfolge} in der Zeichenkette @code{zeichenkette} ab Position
@code{position} an. Gibt @code{0} zurück, wenn @code{teilzeichenfolge}
nicht in @code{zeichenkette} enthalten ist:

@example
mysql> select LOCATE('bar', 'foobarbar',5);
        -> 7
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex INSTR()
@item INSTR(zeichenkette,teilzeichenfolge)
Gibt die Position des ersten Auftretens der Teilzeichenfolge
@code{teilzeichenfolge} in der Zeichenkette @code{zeichenkette} an. Das ist
dasselbe wie @code{LOCATE()} mit zwei Argumenten, ausser dass die Argumente
vertauscht sind:

@example
mysql> select INSTR('foobarbar', 'bar');
        -> 4
mysql> select INSTR('xbar', 'foobar');
        -> 0
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex LPAD()
@item LPAD(zeichenkette,laenge,fuellzeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, links aufgefüllt mit der
Zeichenkette @code{fuellzeichenkette}, bis @code{zeichenkette}
@code{laenge} Zeichen lang ist. Wenn @code{zeichenkette} länger als
@code{laenge} ist, wird sie auf @code{laenge} Zeichen verkürzt.

@example
mysql> select LPAD('hi',4,'??');
        -> '??hi'
@end example

@findex RPAD()
@item RPAD(zeichenkette,laenge,fuellzeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, rechts aufgefüllt mit der
Zeichenkette @code{fuellzeichenkette}, bis @code{zeichenkette}
@code{laenge} Zeichen lang ist. Wenn @code{zeichenkette} länger als
@code{laenge} ist, wird sie auf @code{laenge} Zeichen verkürzt.

@example
mysql> select RPAD('hi',5,'?');
        -> 'hi???'
@end example

@findex LEFT()
@item LEFT(zeichenkette,laenge)
Gibt die äußersten linken @code{laenge} Zeichen der Zeichenkette
@code{zeichenkette} zurück:

@example
mysql> select LEFT('foobarbar', 5);
        -> 'fooba'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex RIGHT()
@item RIGHT(zeichenkette,laenge)
Gibt die äußersten rechten @code{laenge} Zeichen der Zeichenkette
@code{zeichenkette} zurück:

@example
mysql> select RIGHT('foobarbar', 4);
        -> 'rbar'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex SUBSTRING()
@findex MID()
@item SUBSTRING(zeichenkette,position,laenge)
@itemx SUBSTRING(zeichenkette FROM position FOR laenge)
@itemx MID(zeichenkette,position,laenge)
Gibt eine @code{laenge} Zeichen lange Teilzeichenfolge der Zeichenkette
@code{zeichenkette} ab Position @code{position} zurück. Die abweichende
Form, die @code{FROM} benutzt, ist ANSI-SQL92-Syntax:

@example
mysql> select SUBSTRING('Heinzholger',5,6);
        -> 'zholge'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex SUBSTRING()
@item SUBSTRING(zeichenkette,position)
@item SUBSTRING(zeichenkette FROM position)
Gibt eine Teilzeichenfolge der Zeichenkette @code{zeichenkette} ab Position
@code{position} zurück:

@example
mysql> select SUBSTRING('Heinzholger',5);
        -> 'zholger'
mysql> select SUBSTRING('foobarbar' FROM 4);
        -> 'barbar'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex SUBSTRING_INDEX()
@item SUBSTRING_INDEX(zeichenkette,begrenzer,zaehler)
Gibt die Teilzeichenfolge von Zeichenkette @code{zeichenkette} vor
@code{zaehler} Vorkommen des Begrenzers @code{begrenzer} zurück. Wenn
@code{zaehler} positiv ist, wird alle links vom letzten Begrenzer
zurückgegeben (von links gezählt). Wenn @code{zaehler} negativ ist, wird
alles rechts vom letzten Begrenzer (von rechts gezählt) zurückgegeben:

@example
mysql> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
        -> 'www.mysql'
mysql> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
        -> 'mysql.com'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex LTRIM()
@item LTRIM(zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, bei der führende
Leerzeichen entfernt wurden:

@example
mysql> select LTRIM('  barbar');
        -> 'barbar'
@end example

@findex RTRIM()
@item RTRIM(zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, bei der Leerzeichen am
Ende entfernt wurden:

@example
mysql> select RTRIM('barbar   ');
        -> 'barbar'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex TRIM()
@item TRIM([[BOTH | LEADING | TRAILING] [entfernzeichenkette] FROM] zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle
@code{entfernzeichenkette}-Präfixe und / oder -Suffixe entfernt wurden.
Wenn keiner der Spezifizierer @code{BOTH}, @code{LEADING} oder
@code{TRAILING} angegeben wird, wird @code{BOTH} angenommen. Wenn
@code{entfernzeichenkette} nicht angegeben ist, werden Leerzeichen entfernt:

@example
mysql> select TRIM('  bar   ');
        -> 'bar'
mysql> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
        -> 'barxxx'
mysql> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
        -> 'bar'
mysql> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
        -> 'barx'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex SOUNDEX()
@item SOUNDEX(zeichenkette)
Gibt eine Soundex-Zeichenkette von @code{zeichenkette} zurück. Zwei
Zeichenketten, die fast gleich klingen, sollten identische
Soundex-Zeichenketten haben. Eine Standard-Soundex-Zeichenkette ist 4
Zeichen lang, aber die @code{SOUNDEX()}-Funktion gibt eine beliebig lange
Zeichenkette zurück. Sie können @code{SUBSTRING()} auf das Ergebnis
anwenden, um eine Standard-Soundex-Zeichenkette zu erhalten. Alle nicht
alphanumerischen Zeichen in der angegebenen Zeichenkette werden ignoriert.
Alle internationalen alphabetischen Zeichen ausserhalb des Wertebereichs A
bis Z werden als Vokale behandelt:

@example
mysql> select SOUNDEX('Hello');
        -> 'H400'
mysql> select SOUNDEX('Quadratically');
        -> 'Q36324'
@end example

@findex SPACE()
@item SPACE(N)
Gibt eine Zeichenkette zurück, die aus @code{N} Leerzeichen besteht:

@example
mysql> select SPACE(6);
        -> '      '
@end example

@findex REPLACE()
@item REPLACE(zeichenkette,von_zeichenkette,zu_zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle Vorkommen
der Zeichenkette @code{von_zeichenkette} durch die Zeichenkette
@code{zu_zeichenkette} ersetzt wurden:

@example
mysql> select REPLACE('www.mysql.com', 'w', 'Ww');
        -> 'WwWwWw.mysql.com'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex REPEAT()
@item REPEAT(zeichenkette,zaehler)
Gibt eine Zeichenkette zurück, die aus der Zeichenkette @code{zeichenkette}
besteht, die @code{zaehler} mal wiederholt wurde. Wenn @code{zaehler <= 0}
ist, wird eine leere Zeichenkette zurückgegeben. Gibt @code{NULL} zurück,
wenn @code{zeichenkette} oder @code{zaehler} @code{NULL} sind:

@example
mysql> select REPEAT('MySQL', 3);
        -> 'MySQLMySQLMySQL'
@end example

@findex REVERSE()
@item REVERSE(zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} in umgedrehter Reihenfolge der
Zeichen zurück:

@example
mysql> select REVERSE('abc');
        -> 'cba'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex INSERT()
@item INSERT(zeichenkette,position,laenge,neue_zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, wobei eine
Teilzeichenfolge ab Position @code{position} mit @code{laenge} Zeichen
Länge durch die Zeichenkette @code{neue_zeichenkette} ersetzt wurde:

@example
mysql> select INSERT('Heinzholger', 6, 4, 'DIET');
        -> 'HeinzDIETer'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex ELT()
@item ELT(N,zeichenkette1,zeichenkette2,zeichenkette3,...)
Gibt @code{zeichenkette1} zurück, wenn @code{N} = @code{1} ist,
@code{zeichenkette2}, wenn @code{N} = @code{2} ist usw.. Gibt @code{NULL}
zurück, wenn @code{N} kleiner als @code{1} oder größer als die Anzahl von
Argumenten ist. @code{ELT()} ist das Komplement von @code{FIELD()}:

@example
mysql> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
        -> 'ej'
mysql> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
        -> 'foo'
@end example

@findex FIELD()
@item FIELD(zeichenkette,zeichenkette1,zeichenkette2,zeichenkette3,...)
Gibt den Index von @code{zeichenkette} in der Liste @code{zeichenkette1},
@code{zeichenkette2}, @code{zeichenkette3}, @code{...} zurück. Gibt
@code{0} zurück, wenn @code{zeichenkette} nicht gefunden wird.
@code{FIELD()} ist das Komplement von @code{ELT()}:

@example
mysql> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 2
mysql> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 0
@end example

@findex FIND_IN_SET()
@item FIND_IN_SET(zeichenkette,zeichenkettenliste)
Gibt einen Wert @code{1} bis @code{N} zurück, wenn die Zeichenkette
@code{zeichenkette} in der Liste @code{zeichenkettenliste} ist, die aus
@code{N} Teilzeichenfolgen besteht. Eine Zeichenkettenliste ist eine
Zeichenkette, die aus Teilzeichenfolgen zusammen gesetzt ist, die durch
@samp{,}-Zeichen getrennt sind. Wenn das erste Argument eine
Zeichenketten-Konstante ist und das zweite eine Spalte des Typs @code{SET},
wird die @code{FIND_IN_SET()}-Funktion optimiert, Bit-Arithmetik zu
benutzen! Gibt @code{0} zurück, wenn @code{zeichenkette} nicht in
@code{zeichenkettenliste} ist oder wenn @code{zeichenkettenliste} die leere
Zeichenkette ist. Gibt @code{NULL} zurück, wenn eines oder beide Argumente
@code{NULL} sind. Diese Funktion funktioniert nicht korrekt, wenn das erste
Argument ein @samp{,} enthält:

@example
mysql> SELECT FIND_IN_SET('b','a,b,c,d');
        -> 2
@end example

@findex MAKE_SET()
@item MAKE_SET(bits,zeichenkette1,zeichenkette2,...)
Gibt einen Satz (eine Zeichenkette, die Teilzeichenfolgen enthält, die
durch @samp{,} getrennt sind) zurück, der aus Zeichenketten besteht, die
das entsprechende Bit in @code{bits} gesetzt haben. @code{zeichenkette1}
entspricht Bit 0, @code{zeichenkette2} Bit 1 usw. @code{NULL}-Zeichenketten
in @code{zeichenkette1}, @code{zeichenkette2} usw. werden nicht an das
Ergebnis angehängt:

@example
mysql> SELECT MAKE_SET(1,'a','b','c');
        -> 'a'
mysql> SELECT MAKE_SET(1 | 4,'hallo','liebe','welt');
        -> 'hallo,welt'
mysql> SELECT MAKE_SET(0,'a','b','c');
        -> ''
@end example

@findex EXPORT_SET()
@item EXPORT_SET(bits,an,aus,[trennzeichen,[anzahl_bits]])
Gibt eine Zeichenkette zurück, in der Sie für jedes bit, das in 'bit'
gesetzt ist, eine 'an'-Zeichenkette erhalten, und für jedes zurückgesetzte
Bit eine 'aus'-Zeichenkette. Jede Zeichenkette wird mit 'trennzeichen'
getrennt (vorgabemäßig ','), und nur die 'anzahl_bits' (vorgabemäßig 64)
von 'bits' wird benutzt:

@example
mysql> select EXPORT_SET(5,'Y','N',',',4)
        -> Y,N,Y,N
@end example

@findex LCASE()
@findex LOWER()
@item LCASE(zeichenkette)
@itemx LOWER(zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle Zeichen in
Kleinschreibung gemäß dem aktuellen Zeichensatz-Mapping (Vorgabe ist
ISO-8859-1 Latin1) umgewandelt wurden:

@example
mysql> select LCASE('HEINZholger');
        -> 'heinzholger'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex UCASE()
@findex UPPER()
@item UCASE(zeichenkette)
@itemx UPPER(zeichenkette)
Gibt die Zeichenkette @code{zeichenkette} zurück, bei der alle Zeichen in
Großschreibung gemäß dem aktuellen Zeichensatz-Mapping (Vorgabe ist
ISO-8859-1 Latin1) umgewandelt wurden:

@example
mysql> select UCASE('Hej');
        -> 'HEJ'
@end example

Diese Funktion ist Multi-Byte-sicher.

@findex FILE
@findex LOAD_FILE()
@item LOAD_FILE(datei)
Liest die Datei @code{datei} und gibt den Dateiinhalt als Zeichenkette
zurück. Die Datei muss auf dem Server sein, Sie müssen den vollen Pfadnamen
zur Datei angeben und Sie müssen die @strong{file}-Berechtigung besitzen.
Die Datei muss von allen lesbar sein und kleiner als
@code{max_allowed_packet}.

Wenn die Datei nicht existiert oder aus den oben genannten Gründen nicht
gelesen werden kann, gibt die Funktion @code{NULL} zurück:

@example
mysql> UPDATE tabelle
           SET blob_spalte=LOAD_FILE("/tmp/bild")
           WHERE id=1;
@end example
@end table

Wenn Sie nicht MySQL-Version 3.23 benutzen, müssen Sie das Lesen der Datei
innerhalb Ihrer Applikation durchführen und ein @code{INSERT}-Statement
erzeugen, um die Datenbank mit der Dateiinformation zu aktualisieren. Eine
Art, das zu tun, finden Sie - wenn Sie die MySQL++-Bibliothek benutzen -
unter
@uref{http://www.mysql.com/documentation/mysql++/mysql++-examples.html}.

MySQL konvertiert Zahlen bei Bedarf automatisch in Zeichenketten, und
umgekehrt:

@example
mysql> SELECT 1+"1";
        -> 2
mysql> SELECT CONCAT(2,' test');
        -> '2 test'
@end example

Wenn Sie eine Zahl explizit in eine Zeichenkette umwandeln wollen,
übergeben Sie sie als Argument an @code{CONCAT()}.

Wenn in einer Zeichenketten-Funktion eine binäre Zeichenkette als Argument
angegeben wird, ist die resultierende Zeichenkette ebenfalls eine binäre
Zeichenkette. Eine Zahl, die in eine Zeichenkette umgewandelt wird, wird
als binäre Zeichenkette behandelt. Das betrifft nur Vergleichsoperationen.



@menu
* String comparison functions::  
* Case Sensitivity Operators::  
@end menu

@node String comparison functions, Case Sensitivity Operators, String functions, String functions
@c German node Zeichenketten-Vergleichsfunktionen
@subsubsection Zeichenketten-Vergleichsfunktionen

@findex Zeichenketten-Vergleichsfunktionen
@findex Funktionen, Zeichenketten-Vergleich

@cindex Groß-/Kleinschreibung, in Zeichenketten-Vergleichen
@cindex Zeichenketten-Vergleiche, Groß-/Kleinschreibung

Normalerweise wird ein Vergleich unter Berücksichtigung der
Groß-/Kleinschreibung durchgeführt, wenn irgend ein Ausdruck in einem
Zeichenkettenvergleich abhängig von der verwendeten Groß-/Kleinschreibung
ist.

@table @code
@findex LIKE
@item ausdruck LIKE muster [ESCAPE 'fluchtzeichen']
Mustervergleich, der den einfachen SQL-Vergleich mit regulären Ausdrücken
benutzt. Gibt @code{1} (TRUE) oder @code{0} (FALSE) zurück. Bei @code{LIKE}
können Sie die folgenden zwei Platzhalterzeichen im Muster benutzen:

@multitable @columnfractions .1 .9
@item @code{%} @tab Entspricht einer beliebigen Anzahl von Zeichen, selbst 0 Zeichen
@item @code{_} @tab Entspricht genau einem Zeichen
@end multitable

@example
mysql> select 'David!' LIKE 'David_';
        -> 1
mysql> select 'David!' LIKE '%D%v%';
        -> 1
@end example

Um auf literale Instanzen des Platzhalterzeichens zu testen, stellen Sie
dem Zeichen ein Fluchtzeichen (Escape-Zeichen) voran. Wenn Sie das
@code{ESCAPE}-Zeichen nicht angeben, wird @samp{\} angenommen:

@multitable @columnfractions .1 .9
@item @code{\%} @tab Entspricht einem @code{%}-Zeichen
@item @code{\_} @tab Entspricht einem @code{_}-Zeichen
@end multitable

@example
mysql> select 'David!' LIKE 'David\_';
        -> 0
mysql> select 'David_' LIKE 'David\_';
        -> 1
@end example

Um ein anderes Fluchtzeichen (Escape-Zeichen) anzugeben, benutzen Sie die
@code{ESCAPE}-Klausel:

@example
mysql> select 'David_' LIKE 'David|_' ESCAPE '|';
        -> 1
@end example

Die folgenden beiden Statements zeigen, dass Zeichenketten-Vergleiche die
Groß-/Kleinschreibung nicht berücksichtigen, solange nicht einer der
Operanden eine binäre Zeichenkette ist:
case insensitive unless one of the operands ist a binäre Zeichenkette:

@example
mysql> select 'abc' LIKE 'ABC';
        -> 1
mysql> SELECT 'abc' LIKE BINARY 'ABC';
        -> 0
@end example

@code{LIKE} ist bei numerischen Ausdrücken zulässig! (Das ist eine
MySQL-Erweiterung zum ANSI-SQL-@code{LIKE}.)

@example
mysql> select 10 LIKE '1%';
        -> 1
@end example

HINWEIS: Weil MySQL die C Escape-Syntax in Zeichenketten benutzt
(beispielsweise @samp{\n}), müssen Sie jedes @samp{\}-Zeichen, das Sie in
@code{LIKE}-Zeichenketten benutzen, verdoppeln. Um zum Beispiel nach
@samp{\n} zu suchen, geben Sie @samp{\\n} ein. Um nach @samp{\} zu suchen,
geben Sie @samp{\\\\} ein (die Backslashes werden einmal vom Parser
entfernt und noch einmal, wenn der Mustervergleich durchgeführt wird, so
dass letztlich ein einzelner Backslash übrig bleibt).

@findex NOT LIKE
@item ausdruck NOT LIKE muster [ESCAPE 'fluchtzeichen']
Dasselbe wie @code{NOT (ausdruck LIKE muster [ESCAPE 'fluchtzeichen'])}.

@cindex mSQL-Kompatibilität
@cindex Kompatibilität, mit mSQL
@findex REGEXP
@findex RLIKE
@item ausdruck REGEXP muster
@itemx ausdruck RLIKE muster
Führt einen Mustervergleich eines Zeichenkettenausdrucks @code{ausdruck}
gegen ein Muster @code{muster} durch. Das Muster kann ein erweiterter
regulärer Ausdruck sein. @xref{Regexp}. Gibt @code{1} zurück, wenn
@code{ausdruck} mit @code{muster} übereinstimmt, ansonsten @code{0}.
@code{RLIKE} ist ein Synonym für @code{REGEXP}, was aus Gründen der
@code{mSQL}-Kompatibilität zur Verfügung steht. HINWEIS: Weil MySQL die
C-Escape-Syntax in Zeichenketten benutzt (beispielsweise @samp{\n}), müssen
Sie jeden @samp{\}, den Sie in Ihren @code{REGEXP}-Zeichenketten benutzen,
verdoppeln. Ab MySQL-Version 3.23.4 berücksichtigt @code{REGEXP} nicht die
verwendete Groß-/Kleinschreibung für normale (nicht binäre)
Zeichenketten:

@example
mysql> select 'Monty!' REGEXP 'm%y%%';
        -> 0
mysql> select 'Monty!' REGEXP '.*';
        -> 1
mysql> select 'new*\n*line' REGEXP 'new\\*.\\*line';
        -> 1
mysql> select "a" REGEXP "A", "a" REGEXP BINARY "A";
        -> 1  0
mysql> select "a" REGEXP "^[a-d]";
        -> 1
@end example

@item
@code{REGEXP} und @code{RLIKE} benutzen den aktuellen Zeichensatz
(vorgabemäßig ISO-8859-1 Latin1), wenn über den Typ eines Zeichens
entschieden wird.

@findex NOT REGEXP
@item ausdruck NOT REGEXP muster
@itemx ausdruck NOT RLIKE muster
Dasselbe wie @code{NOT (ausdruck REGEXP muster)}.

@findex STRCMP()
@item STRCMP(ausdruck1,ausdruck2)
@code{STRCMP()} gibt @code{0} zurück, wenn die Zeichenketten gleich sind,
@code{-1}, wenn das erste Argument kleiner als das zweite ist (nach der
aktuellen Sortierreihenfolge), und ansonsten @code{1}:

@example
mysql> select STRCMP('text', 'text2');
        -> -1
mysql> select STRCMP('text2', 'text');
        -> 1
mysql> select STRCMP('text', 'text');
        -> 0
@end example

@findex MATCH ... AGAINST()
@item MATCH (spalte1,spalte2,...) AGAINST (ausdruck)
@code{MATCH ... AGAINST()} wird für Volltextsuche benutzt und gibt die
Relevanz zurück - ein Ähnlichkeitsmaß zwischen dem Text in den Spalten
@code{(spalte1,spalte2,...)} und der Anfrage @code{ausdruck}. Die Relevanz
ist eine positive Fließkommazahl. 0 Relevanz bedeutet keine Ähnlichkeit.
Damit @code{MATCH ... AGAINST()} funktioniert, muss zuerst ein
@strong{FULLTEXT}-Index erzeugt werden. @xref{CREATE TABLE, , @code{CREATE TABLE}}. @code{MATCH ... AGAINST()} ist verfügbar ab MySQL-Version 3.23.23.
Für Details und Benutzungsbeispiele siehe @pxref{Fulltext Search}.
@end table


@node Case Sensitivity Operators,  , String comparison functions, String functions
@c German node Operatoren und Groß-/Kleinschreibung
@subsubsection Groß-/Kleinschreibung

@findex Casts

@cindex Cast-Operatoren
@cindex Operatoren, Cast-

@table @code
@findex BINARY
@item @code{BINARY}
Der @code{BINARY}-Operator macht die folgende Zeichenkette zu einer binären
Zeichenkette. Das ist eine einfache Möglichkeit, einen Spaltenvergleich
zwangsweise in Abhängigkeit von der verwendeten Groß-/Kleinschreibung
durchzuführen, selbst wenn die Spalte nicht als @code{BINARY} oder
@code{BLOB} definiert ist:
@example
mysql> select "a" = "A";
        -> 1
mysql> select BINARY "a" = "A";
        -> 0
@end example

@code{BINARY} wurde in MySQL-Version 3.23.0 eingeführt.

Beachten Sie, dass MySQL in manchen Fällen nicht in der Lage ist, den Index
effizient zu benutzen, wenn Sie eine indizierte Spalte zu @code{BINARY}
machen.
@end table

Wenn Sie ein Blob ohne Berücksichtigung der Groß-/Kleinschreibung
vergleichen wollen, können Sie den Blob jederzeit in Großschreibung
umwandeln, bevor Sie den Vergleich durchführen:

@example
SELECT 'A' LIKE UPPER(blob_spalte) FROM tabelle;
@end example

Wir planen, bald Casting zwischen unterschiedlichen Zeichensätzen
einzuführen, um Zeichenketten-Vergleiche noch flexibler zu machen.


@node Numeric Functions, Date and time functions, String functions, Functions
@c German node Numerische Funktionen
@subsection Numerische Funktionen



@menu
* Arithmetic functions::        
* Mathematical functions::      
@end menu

@node Arithmetic functions, Mathematical functions, Numeric Functions, Numeric Functions
@c German node Arithmetische Funktionen
@subsubsection Arithmetische Operationen

Es gibt die üblichen arithmetischen Operatoren. Beachten Sie, dass das
Ergebnis im Falle von @samp{-}, @samp{+} und @samp{*} mit
@code{BIGINT}-Genauigkeit (64-Bit) berechnet wird, wenn beide Argumente
Ganzzahlen sind!

@cindex Operationen, arithmetische
@cindex arithmetische Ausdrücke
@table @code
@findex + (Addition)
@findex Addition (+)
@item +
Addition:
@example
mysql> select 3+5;
        -> 8
@end example

@findex - (Subtraktion)
@findex Subtraktion (-)
@item -
Subtraktion:
@example
mysql> select 3-5;
        -> -2
@end example

@findex * (Multiplikation)
@findex Multiplikation (*)
@item *
Multiplication:
@example
mysql> select 3*5;
        -> 15
mysql> select 18014398509481984*18014398509481984.0;
        -> 324518553658426726783156020576256.0
mysql> select 18014398509481984*18014398509481984;
        -> 0
@end example

Das Ergebnis des letzten Ausdrucks ist falsch, weil die
Ganzzahl-Multiplikation den 64-Bit-Wertebereich von
@code{BIGINT}-Berechnungen überschreitet.

@findex / (Division)
@findex Division (/)
@item /
Division:
@example
mysql> select 3/5;
        -> 0.60
@end example

Division durch 0 erzeugt ein @code{NULL}-Ergebnis:

@example
mysql> select 102/(1-1);
        -> NULL
@end example

Eine Division wird nur dann mit @code{BIGINT}-Arithmetik berechnet, wenn
sie in einem Zusammenhang durchgeführt wird, in dem das Ergebnis in eine
Ganzzahl umgewandelt wird!
@end table


@node Mathematical functions,  , Arithmetic functions, Numeric Functions
@c German node Mathematische Funktionen
@subsubsection Mathematische Funktionen
Alle mathematischen Funktionen geben im Fehlerfall @code{NULL} zurück.

@findex mathematische Funktionen
@findex Funktionen, mathematische

@table @code
@findex - (unäres Minus)
@findex Minus, unäres (-)
@findex unäres Minus (-)
@item -
Unäres Minus. Ändert das Vorzeichen des Arguments:
@example
mysql> select - 2;
        -> -2
@end example

Wenn dieser Operator mit einer @code{BIGINT} benutzt wird, beachten Sie,
dass der Rückgabewert eine @code{BIGINT} ist! Das bedeutet, dass Sie
@code{-} auf Ganzzahlen, die den Wert @code{-2^63} haben könnten, vermeiden
sollten!

@findex ABS()
@item ABS(X)
Gibt den absoluten Wert von @code{X} zurück:
@example
mysql> select ABS(2);
        -> 2
mysql> select ABS(-32);
        -> 32
@end example

Diese Funktion kann bei @code{BIGINT}-Werten sicher benutzt werden.

@findex SIGN()
@item SIGN(X)
Gibt das Vorzeichen des Arguments als @code{-1}, @code{0} oder @code{1}
zurück, abhängig davon, ob @code{X} negativ, 0 oder positiv ist:
@example
mysql> select SIGN(-32);
        -> -1
mysql> select SIGN(0);
        -> 0
mysql> select SIGN(234);
        -> 1
@end example

@findex MOD()
@c German FIX added space before %
@findex % (Modulo)
@findex Modulo (%)
@item MOD(N,M)
@c German FIX added space before %
@itemx %
Modulo (wie der @code{%}-Operator in C). Gibt den Rest von @code{N}
dividiert durch @code{M} zurück:
@example
mysql> select MOD(234, 10);
        -> 4
mysql> select 253% 7;
        -> 1
mysql> select MOD(29,9);
        -> 2
@end example

Diese Funktion kann bei @code{BIGINT}-Werten sicher benutzt werden.

@findex FLOOR()
@item FLOOR(X)
Gibt den größten Ganzzahl-Wert zurück, der nicht größer als @code{X}
ist:
@example
mysql> select FLOOR(1.23);
        -> 1
mysql> select FLOOR(-1.23);
        -> -2
@end example

Beachten Sie, dass der Rückgabewert in eine @code{BIGINT} umgewandelt
wird!

@findex CEILING()
@item CEILING(X)
Gibt den kleinsten Ganzzahl-Wert zurück, der nicht kleiner als @code{X}
ist:
@example
mysql> select CEILING(1.23);
        -> 2
mysql> select CEILING(-1.23);
        -> -1
@end example

Beachten Sie, dass der Rückgabewert in eine @code{BIGINT} umgewandelt wird!

@findex ROUND()
@item ROUND(X)
Gibt das Argument @code{X} zurück, gerundet auf die nächste Ganzzahl:
@example
mysql> select ROUND(-1.23);
        -> -1
mysql> select ROUND(-1.58);
        -> -2
mysql> select ROUND(1.58);
        -> 2
@end example

Beachten Sie, dass das Verhalten von @code{ROUND()} abhängig von der
C-Bibliothek-Implementation ist, wenn das Argument in der Mitte zwischen
zwei Ganzzahlen liegt. Einige runden auf die nächste gerade Zahl, oder
immer nach oben, immer nach unten oder immer Richtung 0. Wenn Sie eine
bestimmte Art zu runden brauchen, sollten Sie statt dessen wohldefinierte
Funktionen wie @code{TRUNCATE()} oder @code{FLOOR()} benutzen.

@findex ROUND()
@item ROUND(X,D)
Gibt das Argument @code{X} zurück, gerundet auf eine Zahl mit @code{D}
Dezimalstellen. Wenn @code{D} @code{0} ist, hat das Ergebnis keinen
Dezimalpunkt oder Bruchteil:

@example
mysql> select ROUND(1.298, 1);
        -> 1.3
mysql> select ROUND(1.298, 0);
        -> 1
@end example

@findex EXP()
@item EXP(X)
Gibt den Wert @code{e} (die Basis des natürlichen Logarithmus) hoch
@code{X} zurück:
@example
mysql> select EXP(2);
        -> 7.389056
mysql> select EXP(-2);
        -> 0.135335
@end example
@findex LOG()
@item LOG(X)
Gibt den natürlichen Logarithmus von @code{X} zurück:
@example
mysql> select LOG(2);
        -> 0.693147
mysql> select LOG(-2);
        -> NULL
@end example
Wenn Sie den Logarithmus einer Zahl @code{X} zu einer beliebigen Basis
@code{B} errechnen wollen, benutzen Sie die Formel @code{LOG(X)/LOG(B)}.

@findex LOG10()
@item LOG10(X)
Gibt den Logarithmus zur Basis 10 von @code{X} zurück:
@example
mysql> select LOG10(2);
        -> 0.301030
mysql> select LOG10(100);
        -> 2.000000
mysql> select LOG10(-100);
        -> NULL
@end example

@findex POW()
@findex POWER()
@item POW(X,Y)
@itemx POWER(X,Y)
Gibt den Wert @code{X} hoch @code{Y} zurück:
@example
mysql> select POW(2,2);
        -> 4.000000
mysql> select POW(2,-2);
        -> 0.250000
@end example

@findex SQRT()
@item SQRT(X)
Gibt die nicht negative Quadratwurzel von @code{X} zurück:
@example
mysql> select SQRT(4);
        -> 2.000000
mysql> select SQRT(20);
        -> 4.472136
@end example

@findex PI()
@item PI()
Gibt den Wert PI zurück. Die vorgabemäßig angezeigte Anzahl von
Dezimalstellen ist 5, aber MySQL benutzt intern die volle doppelte
Genauigkeit für PI.
@example
mysql> select PI();
        -> 3.141593
mysql> SELECT PI()+0.000000000000000000;
        -> 3.141592653589793116
@end example

@findex COS()
@item COS(X)
Gibt den Cosinus von @code{X} zurück, wobei @code{X} in Radianten angegeben
wird:
@example
mysql> select COS(PI());
        -> -1.000000
@end example

@findex SIN()
@item SIN(X)
Gibt den Sinus von @code{X} zurück, wobei @code{X} in Radianten angegeben
wird:
@example
mysql> select SIN(PI());
        -> 0.000000
@end example

@findex TAN()
@item TAN(X)
Gibt den Tangens von @code{X} zurück, wobei @code{X} in Radianten angegeben
wird:
@example
mysql> select TAN(PI()+1);
        -> 1.557408
@end example

@findex ACOS()
@item ACOS(X)
Gibt den Arcuscosinus von @code{X} zurück, dass heißt den Wert, dessen
Cosinus @code{X} ist. Gibt @code{NULL} zurück, wenn @code{X} nicht im
Bereich von @code{-1} bis @code{1} liegt:
@example
mysql> select ACOS(1);
        -> 0.000000
mysql> select ACOS(1.0001);
        -> NULL
mysql> select ACOS(0);
        -> 1.570796
@end example

@findex ASIN()
@item ASIN(X)
Gibt den Arcussinus von @code{X} zurück, das heißt den Wert, dessen Sinus
@code{X} ist. Gibt @code{NULL} zurück, wenn @code{X} nicht im Bereich von
@code{-1} bis @code{1} liegt:
@example
mysql> select ASIN(0.2);
        -> 0.201358
mysql> select ASIN('foo');
        -> 0.000000
@end example

@findex ATAN()
@item ATAN(X)
Gibt den Arcustangens von @code{X} zurück, das heißt den Wert, dessen
Tangens @code{X} ist:
@example
mysql> select ATAN(2);
        -> 1.107149
mysql> select ATAN(-2);
        -> -1.107149
@end example

@findex ATAN2()
@item ATAN2(Y,X)
Gibt den Arcustangens der beiden Variablen @code{X} und @code{Y} zurück.
Das ähnelt der Berechnung des Arcustangens von @code{Y / X}, ausser dass
die Vorzeichen beider Argumente benutzt werden, um den Quadranten des
Ergebnisses zu bestimmen:
@example
mysql> select ATAN(-2,2);
        -> -0.785398
mysql> select ATAN(PI(),0);
        -> 1.570796
@end example

@findex COT()
@item COT(X)
Gibt den Cotangens von @code{X} zurück:
@example
mysql> select COT(12);
        -> -1.57267341
mysql> select COT(0);
        -> NULL
@end example

@findex RAND()
@item RAND()
@itemx RAND(N)
Gibt eine Zufallszahl (Fließkommawert) im Bereich von @code{0} bis
@code{1.0} zurück. Wenn ein Ganzzahl-Argument @code{N} angegeben wird, wird
es als Ausgangswert benutzt:
@example
mysql> select RAND();
        -> 0.5925
mysql> select RAND(20);
        -> 0.1811
mysql> select RAND(20);
        -> 0.1811
mysql> select RAND();
        -> 0.2079
mysql> select RAND();
        -> 0.7888
@end example
Sie können eine Spalte mit @code{RAND()}-Werten nicht in einer @code{ORDER
BY}-Klausel verwenden, weil @code{ORDER BY} die Spalte mehrfach auswerten
würde. In MySQL-Version 3.23 können Sie jedoch folgendes tun:
@code{SELECT * FROM tabelle ORDER BY RAND()}

Das ist nützlich, um eine Zufallsstichprobe aus @code{SELECT * FROM
tabelle1,tabelle2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000} zu
erhalten.

Beachten Sie, dass ein @code{RAND()} in einer @code{WHERE}-Klausel jedes
Mal von Neuem ausgewertet wird, wenn @code{WHERE} ausgeführt wird.

@findex LEAST()
@item LEAST(X,Y,...)
Mit zwei oder mehr Argumenten gibt die Funktion das kleinste Argument (das
mit dem niedrigsten Wert) zurück. Die Argumente werden nach folgenden
Regeln verglichen:

@itemize @bullet
@item
Wenn der Rückgabewert in einem @code{INTEGER}-Zusammenhang benutzt wird
oder alle Argumente Ganzzahl-Werte sind, werden sie als Ganzzahlen
verglichen.

@item
Wenn der Rückgabewert in einem @code{REAL}-Zusammenhang benutzt wird oder
alle Argumente Realzahlen sind, werden sie als Realzahlen verglichen.

@item
Wenn irgend ein Argument eine von der Groß-/Kleinschreibung abhängige
Zeichenkette ist, werden die Argumente als Zeichenketten, die von der
Groß-/Kleinschreibung abhängen, verglichen.

@item
In sonstigen Fällen werden die Argumente als Zeichenketten verglichen, die
nicht von der Groß-/Kleinschreibung abhängen:
@end itemize

@example
mysql> select LEAST(2,0);
        -> 0
mysql> select LEAST(34.0,3.0,5.0,767.0);
        -> 3.0
mysql> select LEAST("B","A","C");
        -> "A"
@end example
In MySQL-Versionen vor Version 3.22.5 können Sie @code{MIN()} statt
@code{LEAST} benutzen.

@findex GREATEST()
@item GREATEST(X,Y,...)
Gibt das größte Argument (das mit dem höchsten Wert) zurück. Die Argumente
werden nach denselben Regeln wie bei @code{LEAST} verglichen:
@example
mysql> select GREATEST(2,0);
        -> 2
mysql> select GREATEST(34.0,3.0,5.0,767.0);
        -> 767.0
mysql> select GREATEST("B","A","C");
        -> "C"
@end example
In MySQL-Versionen vor Version 3.22.5 können Sie @code{MAX()} statt
@code{GREATEST} benutzen.

@findex DEGREES()
@item DEGREES(X)
Gibt das Argument @code{X} zurück, von Radianten zu Grad umgewandelt:
@example
mysql> select DEGREES(PI());
        -> 180.000000
@end example

@findex RADIANS()
@item RADIANS(X)
Gibt das Argument @code{X} zurück, von Grad zu Radianten umgewandelt:
@example
mysql> select RADIANS(90);
        -> 1.570796
@end example

@findex TRUNCATE()
@item TRUNCATE(X,D)
Gibt die Zahl @code{X} zurück, auf @code{D} Dezimalstellen beschnitten.
Wenn @code{D} @code{0} ist, hat das Ergebnis keinen Dezimalpunkt oder
Bruchteil:
@example
mysql> select TRUNCATE(1.223,1);
        -> 1.2
mysql> select TRUNCATE(1.999,1);
        -> 1.9
mysql> select TRUNCATE(1.999,0);
        -> 1
@end example

Beachten Sie, dass Dezimalzahlen in Computern normalerweise nicht als
exakte Zahlen, sondern als Double-Werte gespeichert werden. Daher können
verwirrende Ergebnisse wie im folgenden Beispiel auftreten:

@cindex Rundungsfehler
@example
mysql> select TRUNCATE(10.28*100,0);
       -> 1027
@end example

Das Obige passiert, weil 10.28 tatsächlich als etwas wie
10.2799999999999999 gespeichert wird.
@end table


@node Date and time functions, Other Functions, Numeric Functions, Functions
@c German node Datums- und Zeit-Funktionen
@subsection Datums- und Zeit-Funktionen

@findex Datums- und Zeit-Funktionen
@findex Funktionen, Datums- und Zeit-

Eine Beschreibung des Wertebereichs aller Typen und der gültigen Formate
für Datums- und Zeitwerte finden Sie unter @ref{Date and time types}.

Hier ist ein Beispiel, das Datums-Funktionen benutzt. Die unten stehende
Anfrage wählt alle Datensätze mit einem @code{datum_spalte}-Wert innerhalb
der letzten 30 Tage aus:

@example
mysql> SELECT etwas FROM tabelle
           WHERE TO_DAYS(NOW()) - TO_DAYS(datum_spalte) <= 30;
@end example

@table @code
@findex DAYOFWEEK()
@item DAYOFWEEK(datum)
Gibt den Wochentag-Index zurück.

Für @code{datum} gilt: @code{1} = Sonntag, @code{2} = Montag, ... @code{7}
= Samstag). Diese Index-Werte entsprechen dem ODBC-Standard:

@example
mysql> select DAYOFWEEK('1998-02-03');
        -> 3
@end example

@findex WEEKDAY()
@item WEEKDAY(datum)
Gibt den Wochentag-Index für @code{datum} zurück (@code{0} = Montag,
@code{1} = Dienstag, ... @code{6} = Sonntag):

@example
mysql> select WEEKDAY('1997-10-04 22:23:00');
        -> 5
mysql> select WEEKDAY('1997-11-05');
        -> 2
@end example

@findex DAYOFMONTH()
@item DAYOFMONTH(datum)
Gibt den Tag des Monats für @code{datum} im Bereich @code{1} bis @code{31}
zurück:

@example
mysql> select DAYOFMONTH('1998-02-03');
        -> 3
@end example

@findex DAYOFYEAR()
@item DAYOFYEAR(datum)
Gibt den Tag des Jahres für @code{datum} im Bereich @code{1} bis @code{366}
zurück:

@example
mysql> select DAYOFYEAR('1998-02-03');
        -> 34
@end example

@findex MONTH()
@item MONTH(datum)
Gibt den Monat für @code{datum} im Bereich @code{1} bis @code{12} zurück:

@example
mysql> select MONTH('1998-02-03');
        -> 2
@end example

@findex DAYNAME()
@item DAYNAME(datum)
Gibt den Namen des Wochentags für @code{datum} zurück (auf englisch):

@example
mysql> select DAYNAME("1998-02-05");
        -> 'Thursday'
@end example

@findex MONTHNAME()
@item MONTHNAME(datum)
Gibt den Namen des Monats für @code{datum} zurück (auf englisch):

@example
mysql> select MONTHNAME("1998-02-05");
        -> 'February'
@end example

@findex QUARTER()
@item QUARTER(datum)
Gibt das Quartal des Jahres für @code{datum} im Bereich @code{1} bis
@code{4} zurück:

@example
mysql> select QUARTER('98-04-01');
        -> 2
@end example

@findex WEEK()
@item WEEK(datum)
@itemx WEEK(datum,erste)
Mit einem einzelnen Argument gibt diese Funktion die Woche für @code{datum}
im Bereich @code{0} bis @code{53} zurück (ja, es kann Anfänge der Woche 53
geben), für Orte, in denen Sonntag der erste Wochentag ist. In der Form mit
zwei Argumenten gestattet @code{WEEK()} es, festzulegen, ob die Woche am
Sonntag oder am Montag beginnt. Die Woche beginnt am Sonntag, wenn das
zweite Argument @code{0} ist, und am Montag, wenn das zweite Argument
@code{1} ist:

@example
mysql> select WEEK('1998-02-20');
        -> 7
mysql> select WEEK('1998-02-20',0);
        -> 7
mysql> select WEEK('1998-02-20',1);
        -> 8
mysql> select WEEK('1998-12-31',1);
        -> 53
@end example

@findex YEAR()
@item YEAR(datum)
Gibt das Jahr für @code{datum} im Bereich @code{1000} bis @code{9999}
zurück:

@example
mysql> select YEAR('98-02-03');
        -> 1998
@end example

@item YEARWEEK(datum)
@itemx YEARWEEK(datum,erste)
Gibt Jahr und Woche für ein Datum zurück. Das zweite Argument funktioniert
genau wie das zweite Argument von @code{WEEK()}. Beachten Sie, dass das
Jahr sich in der ersten und letzten Woche des Jahres vom Jahr im
Datums-Argument unterscheiden kann:

@example
mysql> select YEARWEEK('1987-01-01');
        -> 198653
@end example

@findex HOUR()
@item HOUR(zeit)
Gibt die Stunde für @code{zeit} im Bereich @code{0} bis @code{23} zurück:

@example
mysql> select HOUR('10:05:03');
        -> 10
@end example

@findex MINUTE()
@item MINUTE(zeit)
Gibt die Minute für @code{zeit} im Bereich @code{0} bis @code{59} zurück:

@example
mysql> select MINUTE('98-02-03 10:05:03');
        -> 5
@end example

@findex SECOND()
@item SECOND(zeit)
Gibt die Sekunde für @code{zeit} im Bereich @code{0} bis @code{59} zurück:

@example
mysql> select SECOND('10:05:03');
        -> 3
@end example

@findex PERIOD_ADD()
@item PERIOD_ADD(P,N)
Zählt @code{N} Monate zur Periode @code{P} hinzu (im Format @code{YYMM}
oder @code{YYYYMM}). Gibt einen Wert im Format @code{YYYYMM} zurück.

Beachten Sie, dass das Perioden-Argument @code{P} @emph{kein} Datums-Wert
ist:

@example
mysql> select PERIOD_ADD(9801,2);
        -> 199803
@end example

@findex PERIOD_DIFF()
@item PERIOD_DIFF(P1,P2)
Gibt die Anzahl von Monaten zwischen den Perioden @code{P1} und @code{P2}
zurück. @code{P1} und @code{P2} sollten im Format @code{YYMM} oder
@code{YYYYMM} sein.

Beachten Sie, dass die Perioden-Argumente @code{P1} und @code{P2}
@emph{keine} Datumswerte sind:

@example
mysql> select PERIOD_DIFF(9802,199703);
        -> 11
@end example

@findex DATE_ADD()
@findex DATE_SUB()
@findex ADDDATE()
@findex SUBDATE()
@findex EXTRACT()
@item DATE_ADD(datum,INTERVAL ausdruck typ)
@itemx DATE_SUB(datum,INTERVAL ausdruck typ)
@itemx ADDDATE(datum,INTERVAL ausdruck typ)
@itemx SUBDATE(datum,INTERVAL ausdruck typ)

Diese Funktionen führen Datumsberechnungen durch. Sie wurden in
MySQL-Version 3.22 eingeführt. @code{ADDDATE()} und @code{SUBDATE()} sind
Synonyme für @code{DATE_ADD()} und @code{DATE_SUB()}.

In MySQL-Version 3.23 können Sie @code{+} und @code{-} anstelle von
@code{DATE_ADD()} und @code{DATE_SUB()} benutzen, wenn der Ausdruck auf der
rechten Seite eine DATE oder DATETIME-Spalte ist (siehe Beispiel).

@code{datum} ist ein @code{DATETIME}- oder @code{DATE}-Wert, der das
Anfangsdatum festlegt. @code{ausdruck} ist ein Ausdruck, der den
Intervallwert festlegt, der zum Anfangsdatum hinzugezählt oder von diesem
abgezogen wird. @code{ausdruck} ist eine Zeichenkette; sie kann mit einem
@samp{-} für negative Intervalle beginnen. @code{typ} ist ein
Schlüsselwort, das angibt, wie der Ausdruck interpretiert werden soll.

Die verwandte Funktion @code{EXTRACT(typ FROM datum)} gibt das
'typ'-Intervall des Datums zurück.

Folgende Tabelle zeigt, in welchem Zusammenhang die @code{typ}- und
@code{ausdruck}-Argumente stehen:

@multitable @columnfractions .5 .5
@item @code{typ} @strong{wert} @tab @strong{erwartet} @code{ausdruck} @strong{format}
@item @code{SECOND}        @tab @code{Sekunden}
@item @code{MINUTE}        @tab @code{Minuten}
@item @code{HOUR}          @tab @code{Stunden}
@item @code{DAY}           @tab @code{Tage}
@item @code{MONTH}         @tab @code{Monate}
@item @code{YEAR}          @tab @code{Jahre}
@item @code{MINUTE_SECOND} @tab @code{"Minuten:Sekunden"}
@item @code{HOUR_MINUTE}   @tab @code{"Stunden:Minuten"}
@item @code{DAY_HOUR}      @tab @code{"Tage Stunden"}
@item @code{YEAR_MONTH}    @tab @code{"Jahre-Monate"}
@item @code{HOUR_SECOND}   @tab @code{"Stunden:Minuten:Sekunden"}
@item @code{DAY_MINUTE}    @tab @code{"Tage Stunden:Minuten"}
@item @code{DAY_SECOND}    @tab @code{"Tage Stunden:Minuten:Sekunden"}
@end multitable

MySQL erlaubt beliebige Satzzeichen-Begrenzer im @code{ausdruck}-Format.
Die in der Tabelle gezeigten Begrenzer sind Vorschläge. Wenn das
@code{datum}-Argument ein @code{DATE}-Wert ist und Ihre Berechnungen nur
@code{YEAR}, @code{MONTH} und @code{DAY}-Anteile beinhalten (also keine
Zeit-Anteile), ist das Ergebnis ein @code{DATE}-Wert. Ansonsten ist das
Ergebnis ein @code{DATETIME}-Wert:

@example
mysql> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
        -> 1998-01-01 00:00:00
mysql> SELECT INTERVAL 1 DAY + "1997-12-31";
        -> 1998-01-01
mysql> SELECT "1998-01-01" - INTERVAL 1 SECOND;
       -> 1997-12-31 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL 1 SECOND);
        -> 1998-01-01 00:00:00
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL 1 DAY);
        -> 1998-01-01 23:59:59
mysql> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL "1:1" MINUTE_SECOND);
        -> 1998-01-01 00:01:00
mysql> SELECT DATE_SUB("1998-01-01 00:00:00",
                       INTERVAL "1 1:1:1" DAY_SECOND);
        -> 1997-12-30 22:58:59
mysql> SELECT DATE_ADD("1998-01-01 00:00:00",
                       INTERVAL "-1 10" DAY_HOUR);
        -> 1997-12-30 14:00:00
mysql> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
        -> 1997-12-02
@end example

Wenn Sie einen Intervallwert angeben, der zu kurz ist (nicht alle
Intervall-Anteile beinhaltet, die vom @code{typ}-Schlüsselwort erwartet
werden), nimmt MySQL an, dass Sie den äußersten linken Teil des
Intervallwerts ausgelassen haben. Wenn Sie beispielsweise einen @code{typ}
@code{DAY_SECOND} angeben, wird vom Wert von @code{ausdruck} erwartet, dass
dieser Tages-, Stunden-, Minuten- und Sekunden-Anteile enthält. Wenn Sie
einen Wert wie @code{"1:10"} angeben, nimmt MySQL an, dass die Tages- und
Stunden-Anteile fehlen und der Wert Minuten und Sekunden darstellt. Mit
anderen Worten wird @code{"1:10" DAY_SECOND} so interpretiert, dass es
äquivalent zu @code{"1:10" MINUTE_SECOND} ist. Das ist analog zur Weise,
wie MySQL @code{TIME}-Werte interpretiert, die eher vergangene Zeit als
Tageszeit darstellen.

Beachten Sie, dass ein Datumswert automatisch in einen DATETIME-Wert
umgewandelt wird, wenn Sie einen DATE-Wert zu etwas hinzuzählen oder von
etwas abziehen, das einen Zeit-Anteil hat:

@example
mysql> select date_add("1999-01-01", interval 1 day);
       -> 1999-01-02
mysql> select date_add("1999-01-01", interval 1 hour);
       -> 1999-01-01 01:00:00
@end example

Wenn Sie wirklich falsche Datumsangaben benutzen, ist das Ergebnis
@code{NULL}. Wenn Sie @code{MONTH}, @code{YEAR_MONTH} oder @code{YEAR}
hinzuzählen und das Datumsergebnis einen Tag hat, der größer ist als der
höchste Tag für den neuen Monat, wird der Tag auf den höchsten Tag des
neuen Monats angepasst:

@example
mysql> select DATE_ADD('1998-01-30', Interval 1 month);
        -> 1998-02-28
@end example

Beachten Sie, dass das Wort @code{INTERVAL} und das
@code{typ}-Schlüsselwort in den vorstehenden Beispielen nicht von der
verwendeten Groß-/Kleinschreibung abhängen.

@findex EXTRACT()
@item EXTRACT(typ FROM datum)

Die @code{EXTRACT()}-Funktion benutzt dieselbe Art von
Intervalltyp-Spezifikatoren wie @code{DATE_ADD()} oder @code{DATE_SUB()},
extrahiert aber Anteile aus dem Datum, statt Datumsberechnungen
durchzuführen:

@example
mysql> SELECT EXTRACT(YEAR FROM "1999-07-02");
       -> 1999
mysql> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
       -> 199907
mysql> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
       -> 20102
@end example

@findex TO_DAYS()
@item TO_DAYS(datum)
Gibt für ein Datum @code{datum} eine Tagesanzahl zurück (die Anzahl von
Tagen seit dem Jahr 0):

@example
mysql> select TO_DAYS(950501);
        -> 728779
mysql> select TO_DAYS('1997-10-07');
        -> 729669
@end example

@code{TO_DAYS()} ist nicht für die Benutzung mit Werten vor der Einführung
des Gregorianischen Kalenders (1582) vorgesehen, weil es nicht die Tage
berücksichtigt, die verloren gingen, als der Kalender geändert wurde.

@findex FROM_DAYS()
@item FROM_DAYS(N)
Gibt für eine Tagesanzahl @code{N} einen @code{DATE}-Wert zurück:

@example
mysql> select FROM_DAYS(729669);
        -> '1997-10-07'
@end example

@code{FROM_DAYS()} ist nicht für die Benutzung mit Werten vor der Einführung
des Gregorianischen Kalenders (1582) vorgesehen, weil es nicht die Tage
berücksichtigt, die verloren gingen, als der Kalender geändert wurde.

@findex DATE_FORMAT()
@item DATE_FORMAT(datum,format)
Formatiert den @code{datum}-Wert gemäß der @code{format}-Zeichenkette.
Folgende Spezifikatoren können in der @code{format}-Zeichenkette benutzt
werden:
@multitable @columnfractions .1 .6
@item @code{%M} @tab Monatsname auf englisch (@code{January} bis @code{December})
@item @code{%W} @tab Name des Wochentags auf englisch (@code{Sunday} bis @code{Saturday})
@item @code{%D} @tab Tag des Monats mit englischem Suffix (@code{1st}, @code{2nd}, @code{3rd} usw.)
@item @code{%Y} @tab Jahr, numerisch, 4 Ziffern
@item @code{%y} @tab Jahr, numerisch, 2 Ziffern
@item @code{%X} @tab Jahr der Woche, wobei Sonntag der erste Tag der Woche ist, numerisch, 4 Ziffern, benutzt mit '%V'
@item @code{%x} @tab Jahr der Woche, wobei Montag der erste Tag der Woche ist, numerisch, 4 Ziffern, benutzt mit '%v'
@item @code{%a} @tab Abgekürzter Name des Wochentags auf englisch (@code{Sun}..@code{Sat})
@item @code{%d} @tab Tag des Monats, numerisch (@code{00} bis @code{31})
@item @code{%e} @tab Tag des Monats, numerisch (@code{0} bis @code{31})
@item @code{%m} @tab Monat, numerisch (@code{01} bis @code{12})
@item @code{%c} @tab Monat, numerisch (@code{1} bis @code{12})
@item @code{%b} @tab Abgekürzter Monatsname auf englisch (@code{Jan} bis @code{Dec})
@item @code{%j} @tab Tag des Jahrs (@code{001} bis @code{366})
@item @code{%H} @tab Stunde (@code{00} bis @code{23})
@item @code{%k} @tab Stunde (@code{0} bis @code{23})
@item @code{%h} @tab Stunde (@code{01} bis @code{12})
@item @code{%I} @tab Stunde (@code{01} bis @code{12})
@item @code{%l} @tab Stunde (@code{1} bis @code{12})
@item @code{%i} @tab Minuten, numerisch (@code{00} bis @code{59})
@item @code{%r} @tab Uhrzeit, 12-Stunden-Format (@code{hh:mm:ss [AP]M})
@item @code{%T} @tab Uhrzeit, 24-Stunden-Format (@code{hh:mm:ss})
@item @code{%S} @tab Sekunden (@code{00} bis @code{59})
@item @code{%s} @tab Sekunden (@code{00} bis @code{59})
@item @code{%p} @tab @code{AM} oder @code{PM}
@item @code{%w} @tab Wochentag (@code{0}=Sonntag bis @code{6}=Samstag)
@item @code{%U} @tab Woche (@code{0} bis @code{53}), wobei Sonntag der erste Tag der Woche ist
@item @code{%u} @tab Woche (@code{0} bis @code{53}), wobei Montag der erste Tag der Woche ist
@item @code{%V} @tab Woche (@code{1} bis @code{53}), wobei Sonntag der erste Tag der Woche ist. Benutzt mit '%X'
@item @code{%v} @tab Woche (@code{1} bis @code{53}), wobei Montag der erste Tag der Woche ist. Benutzt mit '%x'
@item @code{%%} @tab Ein Literal @samp{%}.
@end multitable

Alle anderen Zeichen werden einfach ohne Interpretation ins Ergebnis
kopiert:

@example
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%W%M%Y');
        -> 'Saturday October 1997'
mysql> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
        -> '22:23:00'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                          '%D%y%a%d%m%b%j');
        -> '4th 97 Sat 04 10 Oct 277'
mysql> select DATE_FORMAT('1997-10-04 22:23:00',
                          '%H%k%I%r%T%S%w');
        -> '22 22 10 10:23:00 PM 22:23:00 00 6'
mysql> select DATE_FORMAT('1999-01-01', '%X%V');
        -> '1998 52'
@end example

Ab MySQL-Version 3.23 ist das @samp{%}-Zeichen vor
Format-Spezifikator-Zeichen erforderlich. In früheren Versionen von MySQL
war @samp{%} optional.

@findex TIME_FORMAT()
@item TIME_FORMAT(zeit,format)
Dieses wird benutzt wie die obige @code{DATE_FORMAT()}-Funktion, aber die
@code{format}-Zeichenkette darf nur die Spezifikatoren enthalten, die
Stunden, Minuten und Sekunden handhaben. Andere Spezifikatoren erzeugen
einen @code{NULL}-Wert oder @code{0}.

@findex CURDATE()
@findex CURRENT_DATE
@item CURDATE()
@itemx CURRENT_DATE
Gibt das Datum von heute im @code{'YYYY-MM-DD'}- oder
@code{YYYYMMDD}-format zurück, abhängig davon, ob die Funktion in einem
Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:

@example
mysql> select CURDATE();
        -> '1997-12-15'
mysql> select CURDATE() + 0;
        -> 19971215
@end example

@findex CURTIME()
@findex CURRENT_TIME
@item CURTIME()
@itemx CURRENT_TIME
Gibt die aktuelle Zeit als einen Wert im @code{'HH:MM:SS'}- oder
@code{HHMMSS}-format zurück, abhängig davon, ob die Funktion in einem
Zeichenketten- oder in einem numerischen Zusammenhang benutzt wird:

@example
mysql> select CURTIME();
        -> '23:50:26'
mysql> select CURTIME() + 0;
        -> 235026
@end example

@findex NOW()
@findex SYSDATE()
@findex CURRENT_TIMESTAMP
@item NOW()
@itemx SYSDATE()
@itemx CURRENT_TIMESTAMP
Gibt das aktuelle Datum und die aktuelle Zeit als einen Wert im
@code{'YYYY-MM-DD HH:MM:SS'}- oder @code{YYYYMMDDHHMMSS}-Format zurück,
abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem
numerischen Zusammenhang benutzt wird:

@example
mysql> select NOW();
        -> '1997-12-15 23:50:26'
mysql> select NOW() + 0;
        -> 19971215235026
@end example

@findex UNIX_TIMESTAMP()
@item UNIX_TIMESTAMP()
@itemx UNIX_TIMESTAMP(datum)
Ohne Argument aufgerufen gibt die Funktion einen Unix-Zeitstempel zurück
(Sekunden seit @code{'1970-01-01 00:00:00'} GMT). Wenn
@code{UNIX_TIMESTAMP()} mit einem @code{datum}-Argument aufgerufen wird,
gibt sie den Wert des Arguments als Sekunden seit @code{'1970-01-01
00:00:00'} GMT zurück. @code{datum} kann eine @code{DATE}-Zeichenkette,
eine @code{DATETIME}-Zeichenkette, ein @code{TIMESTAMP} oder eine Zahl im
Format @code{YYMMDD} oder @code{YYYYMMDD} in lokaler Zeit sein:

@example
mysql> select UNIX_TIMESTAMP();
        -> 882226357
mysql> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
        -> 875996580
@end example

Wenn @code{UNIX_TIMESTAMP} auf einer @code{TIMESTAMP}-Spalte benutzt wird,
erhält die Funktion den Wert direkt, ohne implizite
``zeichenkette-zu-unix-zeitstempel''-Umwandlung. Wenn Sie
@code{UNIX_TIMESTAMP()} einen falschen Wert oder einen Wert ausserhalb des
Wertebereichs angeben, gibt sie 0 zurück.

@findex FROM_UNIXTIME()
@item FROM_UNIXTIME(unix_zeitstempel)
Gibt das @code{unix_timestamp}-Argument als Wert im @code{'YYYY-MM-DD
HH:MM:SS'}- oder @code{YYYYMMDDHHMMSS}-Format zurück, abhängig davon, ob
die Funktion in einem Zeichenketten- oder in einem numerischen Zusammenhang
benutzt wird:

@example
mysql> select FROM_UNIXTIME(875996580);
        -> '1997-10-04 22:23:00'
mysql> select FROM_UNIXTIME(875996580) + 0;
        -> 19971004222300
@end example

@findex FROM_UNIXTIME()
@item FROM_UNIXTIME(unix_zeitstempel,format)
Gibt das @code{unix_timestamp}-Argument als Wert zurück, der wie mit der
@code{format}-Zeichenkette angegeben formatiert ist. @code{format} kann
dieselben Spezifikatoren wie die @code{DATE_FORMAT()}-Funktion enthalten:

@example
mysql> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
                            '%Y%D%M%h:%i:%s%x');
        -> '1997 23rd December 03:43:30 x'
@end example

@findex SEC_TO_TIME()
@item SEC_TO_TIME(sekunden)
Gibt das @code{sekunden}-Argument, umgewandelt in Stunden, Minuten und
Sekunden, als Wert im @code{'HH:MM:SS'}- oder @code{HHMMSS}-Format zurück,
abhängig davon, ob die Funktion in einem Zeichenketten- oder in einem
numerischen Zusammenhang benutzt wird:

@example
mysql> select SEC_TO_TIME(2378);
        -> '00:39:38'
mysql> select SEC_TO_TIME(2378) + 0;
        -> 3938
@end example

@findex TIME_TO_SEC()
@item TIME_TO_SEC(zeit)
Gibt das @code{zeit}-Argument, umgewandelt in Sekunden, zurück:

@example
mysql> select TIME_TO_SEC('22:23:00');
        -> 80580
mysql> select TIME_TO_SEC('00:39:38');
        -> 2378
@end example
@end table


@node Other Functions, Group by functions, Date and time functions, Functions
@c German node Weitere Funktionen
@subsection Weitere Funktionen



@menu
* Bit functions::               
* Miscellaneous functions::     
@end menu

@node Bit functions, Miscellaneous functions, Other Functions, Other Functions
@c German node Bit-Funktionen
@subsubsection Bit-Funktionen

@findex arithmetische Funktionen
@findex Bit-Funktionen
@findex Funktionen, arithmetische
@findex Funktionen, Bit-

MySQL benutzt @code{BIGINT}-Berechnungen (64-Bit) für Bit-Operationen, so
dass diese Operatoren einen maximalen Wertebereich von 64 Bits haben.

@table @code
@findex | (bitweises OR)
@findex OR, bitweises
@item |
Bitweises OR:
@example
mysql> select 29 | 15;
        -> 31
@end example

@findex & (bitweises AND)
@findex AND, bitweises
@item &
Bitweises AND:
@example
mysql> select 29 & 15;
        -> 13
@end example

@findex << (left shift)
@item <<
Verschiebt eine @code{BIGINT}-Zahl nach links:
@example
mysql> select 1 << 2;
        -> 4
@end example

@findex >> (right shift)
@item >>
Verschiebt eine @code{BIGINT}-Zahl nach rechts:
@example
mysql> select 4 >> 2;
        -> 1
@end example

@findex ~
@item ~
Invertiert alle Bits:
@example
mysql> select 5 & ~1;
        -> 4
@end example

@findex BIT_COUNT()
@item BIT_COUNT(N)
Gibt die Anzahl von Bits, die im Argument @code{N} gesetzt sind, zurück:
@example
mysql> select BIT_COUNT(29);
        -> 4
@end example
@end table


@node Miscellaneous functions,  , Bit functions, Other Functions
@c German node Verschiedene Funktionen
@subsubsection Verschiedene Funktionen

@findex Verschiedene Funktionen
@findex Funktionen, verschiedene

@table @code
@findex DATABASE()
@item DATABASE()
Gibt den aktuellen Datenbanknamen zurück:

@example
mysql> select DATABASE();
        -> 'test'
@end example

Wenn es keine aktuelle Datenbank gibt, gibt @code{DATABASE()} die leere
Zeichenkette zurück.

@findex USER()
@findex SYSTEM_USER()
@findex SESSION_USER()
@item USER()
@itemx SYSTEM_USER()
@itemx SESSION_USER()
Gibt den aktuellen MySQL-Benutzernamen zurück:

@example
mysql> select USER();
        -> 'heinzholger@@localhost'
@end example

Ab MySQL-Version 3.22.11 beinhaltet dieser Wert den Client-Hostnamen sowie
den Benutzernamen. Sie können nur den Benutzernamen-Anteil wie folgt
extrahieren (was funktioniert, ob der Wert nun einen Hostnamen-Anteil hat
oder nicht):

@example
mysql> select substring_index(USER(),"@@",1);
        -> 'heinzholger'
@end example

@findex PASSWORD()
@item PASSWORD(zeichenkette)

Berechnet eine Passwort-Zeichenkette aus dem Klartext-Passwort
@code{zeichenkette}. Diese Funktion wird benutzt, um MySQL-Passwörter zum
Speichern in der @code{Password}-Spalte der
@code{user}-Berechtigungstabelle zu verschlüsseln:

@example
mysql> select PASSWORD('schlechtespasswort');
        -> '1ccbb34b4e2b2f95'
@end example

@cindex Passwort-Verschlüsselung, Umkehrbarkeit
Die @code{PASSWORD()}-Verschlüsselung ist nicht umkehrbar.

@code{PASSWORD()} führt keine Passwort-Verschlüsselung in der Art durch,
wie Unix-Passwörter verschlüsselt werden. Sie sollten nicht annehmen, dass
Ihr Unix-Passwort und Ihr MySQL-Passwort dasselbe sind. @code{PASSWORD()}
ergibt denselben verschlüsselten Wert, wie er in der Unix-Passwortdatei
gespeichert ist. Siehe @code{ENCRYPT()}.

@findex ENCRYPT()
@item ENCRYPT(zeichenkette[,salt])
Verschlüsselt @code{zeichenkette} unter Benutzung des
Unix-@code{crypt()}-Systemaufrufs. Das @code{salt}-Argument sollte eine
Zeichenkette mit zwei Zeichen sein (ab MySQL-Version 3.22.16 darf
@code{salt} länger als zwei Zeichen sein):

@example
mysql> select ENCRYPT("hello");
        -> 'VxuFAJXVARROc'
@end example

Wenn @code{crypt()} auf Ihrem System nicht verfügbar ist, gibt
@code{ENCRYPT()} immer @code{NULL} zurück.

@code{ENCRYPT()} ignoriert alle ausser den ersten 8 Zeichen von
@code{zeichenkette}, zumindest auf einigen Systemen. Das wird durch den
zugrunde liegenden @code{crypt()}-Systemaufruf festgelegt.

@findex ENCODE()
@item ENCODE(zeichenkette,passwort_zeichenkette)
Verschlüsselt @code{zeichenkette}, indem @code{passwort_zeichenkette} als
Passwort benutzt wird. Um das Ergebnis zu entschlüsseln, benutzen Sie
@code{DECODE()}.

Das Ergebnis ist eine binäre Zeichenkette derselben Länge wie
@code{zeichenkette}. Wenn Sie sie in einer Spalte speichern wollen,
benutzen Sie eine @code{BLOB}-Spalte.

@findex DECODE()
@item DECODE(crypt_zeichenkette,passwort_zeichenkette)
Entschlüsselt die verschlüsselte Zeichenkette @code{crypt_zeichenkette},
indem @code{passwort_zeichenkette} als Passwort benutzt wird.
@code{crypt_zeichenkette} sollte eine Zeichenkette sein, die von
@code{ENCODE()} zurückgegeben wird.

@findex MD5()
@item MD5(zeichenkette)
Berechnet eine MD5-Prüfsumme für die Zeichenkette. Der Wert wird als eine
32 Stellen lange hexadezimale Zahl zurückgegeben, die zum Beispiel als
Hash-Schlüssel benutzt werden kann:

@example
mysql> select MD5("testing");
        -> 'ae2b1fca515949e5d54fb22b8ed95575'
@end example

Das ist ein "RSA Data Sicherheit, Inc. MD5 Message-Digest Algorithm".

@findex LAST_INSERT_ID([ausdruck])
@item LAST_INSERT_ID([ausdruck])
Gibt den letzten automatisch erzeugten Wert zurück, der in eine
@code{AUTO_INCREMENT}-Spalte eingefügt wurde. @xref{mysql_insert_id,,
@code{mysql_insert_id()}}.

@example
mysql> select LAST_INSERT_ID();
        -> 195
@end example

Die letzte ID, die erzeugt wurde, wird im Server für jede Verbindung
separat gespeichert. Sie wird nicht durch andere Clients geändert. Sie wird
nicht einmal geändert, wenn Sie eine andere @code{AUTO_INCREMENT}-Spalte
mit einem nicht 'magischen' Wert aktualisieren (also einem Wert, der nicht
@code{NULL} und nicht @code{0} ist).

Wenn Sie viele Zeilen zugleich mit einem Insert-Statement einfügen, gibt
@code{LAST_INSERT_ID()} den Wert für die erste eingefügte Zeile zurück. Der
Grund dafür liegt darin, dass es Ihnen dadurch ermöglicht wird, dasselbe
@code{INSERT}-Statement auf einfache Weise auf einem anderen Server zu
reproduzieren.

@cindex Zahlenfolgen-Emulation
Wenn @code{ausdruck} als Argument zu @code{LAST_INSERT_ID()} angegeben
wird, wird der Wert des Arguments  von der Funktion zurückgegeben, als
nächster Wert gesetzt, der von @code{LAST_INSERT_ID()} zurückgegeben wird
und als nächster auto_increment-Wert benutzt. Damit können Sie Zahlenfolgen
emulieren:

Erzeugen Sie zuerst die Tabelle:

@example
mysql> create table sequenz (id int not null);
mysql> insert into sequenz values (0);
@end example

Danach kann die Tabelle benutzt werden, um wie folgt Zahlenfolgen zu
erzeugen:

@example
mysql> update sequenz set id=LAST_INSERT_ID(id+1);
@end example

Sie können Zahlenfolgen erzeugen, ohne @code{LAST_INSERT_ID()} aufzurufen,
aber der Nutzen, die Funktion auf diese Art zu benutzen, liegt darin, dass
der ID-Wert im Server als letzter automatisch erzeugter Wert gehalten wird.
Sie können die neue ID auf dieselbe Art abrufen, wie Sie jeden anderen
normalen @code{AUTO_INCREMENT}-Wert in MySQL lesen würden.
@code{LAST_INSERT_ID()} (ohne Argument) zum Beispiel gibt die neue ID
zurück. Die C-API-Funktion @code{mysql_insert_id()} kann ebenfalls benutzt
werden, um den Wert zu erhalten.

Beachten Sie, dass Sie diese Funktion nicht benutzen können, um den Wert
von @code{LAST_INSERT_ID(ausdruck)} abzurufen, nachdem Sie andere
SQL-Statements wie @code{SELECT} oder @code{SET} ausgeführt haben, weil
@code{mysql_insert_id()} nur nach @code{INSERT}- und
@code{UPDATE}-Statements aktualisiert wird.


@findex FORMAT()
@item FORMAT(X,D)
Formatiert die Zahl @code{X} in ein Format wie @code{'#,###,###.##'},
gerundet auf @code{D} Dezimalstellen. Wenn @code{D} @code{0} ist, hat das
Ergebnis keinen Dezimalpunkt oder Bruchteil:

@example
mysql> select FORMAT(12332.123456, 4);
        -> '12,332.1235'
mysql> select FORMAT(12332.1,4);
        -> '12,332.1000'
mysql> select FORMAT(12332.2,0);
        -> '12,332'
@end example

@findex VERSION()
@item VERSION()
Gibt eine Zeichenkette zurück, die die MySQL-Serverversion anzeigt:

@example
mysql> select VERSION();
        -> '3.23.13-log'
@end example

Wenn Ihre Versionsnummer mit @code{-log} endet, bedeutet das, dass Loggen
angeschaltet ist.

@findex CONNECTION_ID()
@item CONNECTION_ID()
Gibt die Verbindungskennnummer (@code{Thread_id}) für die Verbindung
zurück. Jede Verbindung hat ihre eigene eindeutige Kennnummer:

@example
mysql> select CONNECTION_ID();
        -> 1
@end example

@cindex Zeitüberschreitung (Timeout)
@findex GET_LOCK()
@item GET_LOCK(zeichenkette,zeitueberschreitung)
Versucht, eine Sperre mit dem Namen, der durch die Zeichenkette
@code{zeichenkette} angegeben wird, zu erlangen, mit einem Timeout von
@code{zeitueberschreitung} Sekunden. Gibt @code{1} zurück, wenn die Sperre
erfolgreich erlangt wurde, und @code{0}, wenn der Versuch wegen
Zeitüberschreitung abgebrochen wurde, oder @code{NULL}, wenn ein Fehler
auftrat (wenn zum Beispiel kein Arbeitsspeicher mehr frei ist oder der
Thread mit @code{mysqladmin kill} gekillt wurde). Eine Sperre wird
aufgehoben, wenn Sie @code{RELEASE_LOCK()} ausführen, einen neuen
@code{GET_LOCK()} ausführen oder der Thread beendet wird. Diese Funktion
kann benutzt werden, um Applikations-Sperren zu implementieren oder um
Datensatz-Sperren zu simulieren. Sie blockiert Anfragen von anderen Clients
nach Sperren mit demselben Namen; Clients, die sich auf einen angegebenen
Namen für die Sperr-Zeichenkette einigen, können die Zeichenkette benutzen,
um kooperatives beratendes Sperren (advisory locking) auszuführen:

@example
mysql> select GET_LOCK("lock1",10);
        -> 1
mysql> select GET_LOCK("lock2",10);
        -> 1
mysql> select RELEASE_LOCK("lock2");
        -> 1
mysql> select RELEASE_LOCK("lock1");
        -> NULL
@end example

Beachten Sie, dass der zweite @code{RELEASE_LOCK()}-Aufruf @code{NULL}
zurückgibt, weil die Sperre @code{"lock1"} automatisch durch den zweiten
@code{GET_LOCK()}-Aufruf aufgehoben wurde.

@findex RELEASE_LOCK()
@item RELEASE_LOCK(zeichenkette)
Hebt die Sperre auf, die durch die Zeichenkette @code{zeichenkette} benannt
ist, die mit @code{GET_LOCK()} erlangt wurde. Gibt @code{1} zurück, wenn
die Sperre aufgehoben wurde, und @code{0}, wenn die Sperre nicht durch
diesen Thread gemacht wurde (in diesem Fall wird die Sperre nicht
aufgehoben), oder @code{NULL}, wenn die benannte Sperre nicht existiert.
Die Sperre existiert nicht, wenn sie nie durch einen Aufruf von
@code{GET_LOCK()} erlangt wurde oder wenn sie bereits aufgehoben wurde.

@findex BENCHMARK()
@item BENCHMARK(zaehler,ausdruck)
Die @code{BENCHMARK()}-Funktion den Ausdruck @code{ausdruck} wiederholt
@code{zaehler} mal aus. Sie kann benutzt werden, um die Zeit zu ermitteln,
die MySQL benötigt, um den Ausdruck zu verarbeiten. Der Ergebniswert ist
immer @code{0}. Die Funktion ist für die Benutzung im @code{mysql}-Client
gedacht, der die Ausführungszeiten von Anfragen zum Beispiel wie folgt
darstellt:

@example
mysql> select BENCHMARK(1000000,encode("hello","goodbye"));
+----------------------------------------------+
| BENCHMARK(1000000,encode("hello","goodbye")) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (4.74 sec)
@end example

Die berichtete Zeit ist die am Client-Ende verstrichene Zeit, nicht die
Prozessorzeit am Server-Ende. Es ist ratsam, @code{BENCHMARK()} mehrere
Male auszuführen und das Ergebnis unter Berücksichtigung der Last, unter
der die Server-Maschine fährt, zu interpretieren.

@findex INET_NTOA()
@item INET_NTOA(ausdruck)
Gibt die Netzwerk-Adresse (4 oder 8 Bytes) für den numerischen Ausdruck
zurück:

@example
mysql> select INET_NTOA(3520061480);
       ->  "209.207.224.40"
@end example

@findex INET_ATON()
@item INET_ATON(ausdruck)
Gibt eine Ganzzahl zurück, die den numerischen Wert einer Netzwerk-Adresse
darstellt. Adressen können 4-Byte- oder 8-Byte-Adressen sein:

@example
mysql> select INET_ATON("209.207.224.40");
       ->  3520061480
@end example

Die erzeugte Zahl ist immer in Netzwerk-Byte-Reihenfolge; die obige Zahl
wird zum Beispiel errechnet als @code{209*255^3 + 207*255^2 + 224*255
+40}.

@findex MASTER_POS_WAIT()
@item MASTER_POS_WAIT(log_name, log_position)
Blockiert, bis der Slave während der Replikation die festgelegte Position
in der Master-Log-Datei erreicht. Wenn die Master-Information nicht
initialisiert wird, wird NULL zurückgegeben. Wenn der Slave nicht läuft,
blockiert die Funktion und wartet, bis er gestartet wurde, und geht dann
hinter die angegebene Position. Wenn der Slave bereits hinter der
angegebenen Position ist, kehrt die Funktion sofort zurück. Der
Rückgabewert ist die Anzahl von Log-Events, die sie warten muss, um bis zur
angegebenen Position zu kommen, oder NULL in Fehlerfällen. Nützlich für die
Steuerung der Master-Slave-Synchronisation, aber ursprünglich geschrieben,
um das Testen der Replikation zu erleichtern.
@end table


@node Group by functions,  , Other Functions, Functions
@c German node GROUP-BY-Funktionen
@subsection Funktionen zur Benutzung bei @code{GROUP BY}-Klauseln

@findex GROUP-BY-Funktionen
@findex Funktionen, GROUP BY

Wenn Sie in einem Statement eine Gruppierungsfunktion benutzen, die
keine @code{GROUP BY}-Klausel enthält, ist das gleichbedeutend mit der
Gruppierung aller Zeilen.

@table @code
@findex COUNT()
@item COUNT(ausdruck)
Gibt die Anzahl der Zeilen mit Nicht-@code{NULL}-Werten zurück, die
durch ein @code{SELECT}-Statement abgerufen werden:

@example
mysql> select student.student_name,COUNT(*)
           from student,kurs
           where student.student_id=kurs.student_id
           GROUP BY student_name;

@end example

@code{COUNT(*)} ist insofern anders, als es die Anzahl der abgerufenen
Zeilen zurückgibt, egal ob sie @code{NULL}-Werte enthalten oder nicht.

@code{COUNT(*)} ist darauf optimiert, das Ergebnis sehr schnell
zurückzugeben, wenn es mittels eines @code{SELECT} von einer Tabelle
abruft, wenn keine weiteren Spalten abgerufen werden und es keine
@code{WHERE}-Klausel gibt. Beispiel:

@example
mysql> select COUNT(*) from student;
@end example

@findex COUNT(DISTINCT)
@findex DISTINCT
@item COUNT(DISTINCT ausdruck,[ausdruck...])
Gibt die Anzahl unterschiedlicher Nich-@code{NULL}-Werte zurück:

@example
mysql> select COUNT(DISTINCT ergebnisse) from student;
@end example

Bei MySQL erhalten Sie die Anzahl unterschiedlicher
Ausdruckskombinationen, die nicht NULL enthalten, indem Sie eine Liste
von Ausdrücken angeben. In ANSI-SQL müssten Sie eine Verkettung aller
Ausdrücke innerhalb von @code{CODE(DISTINCT ..)} angeben.

@findex AVG()
@item AVG(ausdruck)
Gibt den Durchschnittswert von @code{ausdruck} zurück:

@example
mysql> select student_name, AVG(test_ergebnis)
           from student
           GROUP BY student_name;
@end example

@findex MIN()
@findex MAX()
@item MIN(ausdruck)
@itemx MAX(ausdruck)
Gibt den kleinsten oder größten Wert von @code{ausdruck} zurück.
@code{MIN()} und @code{MAX()} können Zeichenketten-Argumente aufnehmen
und geben in solchen Fällen den kleinsten oder größten Zeichenketten-
Wert zurück. @xref{MySQL indexes}.

@example
mysql> select student_name, MIN(test_ergebnis), MAX(test_ergebnis)
           from student
           GROUP BY student_name;
@end example

@findex SUM()
@item SUM(ausdruck)
Gibt die Summe von @code{ausdruck} zurück. Beachten Sie, dass der
Rückgabewert NULL ist, wenn die Ergebnismenge keine Zeilen hat!

@findex STD()
@findex STDDEV()
@cindex Oracle-Kompatibilität
@cindex Kompatibilität, mit Oracle
@item STD(ausdruck)
@itemx STDDEV(ausdruck)
Gibt die Standardabweichung von @code{ausdruck} zurück. Das ist eine
Erweiterung zu ANSI-SQL. Die @code{STDDEV()}-Form dieser Funktion wird
aus Gründen der Oracle-Kompatibilität zur Verfügung gestellt.

@findex BIT_OR()
@item BIT_OR(ausdruck)
Gibt das bitweise @code{OR} aller Bits in @code{ausdruck} zurück. Die
Berechnung wird mit 64-Bit-(@code{BIGINT})-Genauigkeit durchgeführt.

@findex BIT_AND()
@item BIT_AND(ausdruck)
Gibt das bitweise @code{AND} aller Bits in @code{ausdruck} zurück. Die
Berechnung wird mit 64-Bit-(@code{BIGINT})-Genauigkeit durchgeführt.
@end table

@cindex @code{GROUP BY}, Erweiterungen zu ANSI-SQL
MySQL hat die Benutzung von @code{GROUP BY} erweitert. Sie können
Spalten oder Berechnungen im @code{SELECT}-Ausdruck angeben, die nicht
im @code{GROUP BY}-Teil erscheinen. Das steht für @emph{jeden möglichen
Wert für diese Gruppe}. Das können Sie benutzen, um bessere Performance
zu erzielen, indem Sie Sortieren und Gruppieren unnötiger Bestandteile
vermeiden. Zum Beispiel müssen Sie in folgender Anfrage nicht nach
@code{kunde.name} gruppieren:

@example
mysql> select bestellung.kunde_id,kunde.name,max(zahlungen)
       from bestellung,kunde
       where bestellung.kunde_id = kunde.kunde_id
       GROUP BY bestellung.kunde_id;
@end example

In ANSI-SQL müssten Sie der @code{GROUP BY}-Klausel @code{kunde.name}
hinzufügen. In MySQL ist der Name überflüßig, solange Sie nicht im
ANSI-Modus fahren.

@strong{Benutzen Sie dieses Feature nicht}, wenn die Spalten, die Sie im
@code{GROUP BY}-Teil auslassen, in der Gruppe nicht eindeutig sind!
Sonst erhalten Sie unvorhersagbare Ergebnisse.

In einigen Fällen können Sie @code{MIN()} und @code{MAX()} benutzen, um
einen bestimmten Spaltenwert zu erhalten, selbst wenn er nicht eindeutig
ist. Folgendes gibt den Wert von @code{spalte} aus der Zeile zurück, die
den kleinsten Wert in der @code{sortierung}-Spalte enthält:

@example
substr(MIN(concat(rpad(sortierung,6,' '),spalte)),7)
@end example

@node Data Manipulation, Data Definition, Functions, Reference
@c German node Datenmanipulation
@section Datenmanipulation: @code{SELECT}, @code{INSERT}, @code{UPDATE}, @code{DELETE}



@menu
* SELECT::                      
* HANDLER::                     
* INSERT::                      
* INSERT DELAYED::              
* UPDATE::                      
* DELETE::                      
* TRUNCATE::                    
* REPLACE::                     
* LOAD DATA::                   
@end menu

@node SELECT, HANDLER, Data Manipulation, Data Manipulation
@c German node SELECT
@subsection @code{SELECT}-Syntax

@findex SELECT

@c help SELECT
@example
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
       [HIGH_PRIORITY]
       [DISTINCT | DISTINCTROW | ALL]
    select_ausdruck,...
    [INTO @{OUTFILE | DUMPFILE@} 'datei' export_optionen]
    [FROM tabellenreferenz
        [WHERE where_definition]
        [GROUP BY @{positive_ganzzahl | spalten_name | formel@} [ASC | DESC], ...]
        [HAVING where_definition]
        [ORDER BY @{positive_ganzzahl | spalten_name | formel@} [ASC | DESC] ,...]
        [LIMIT [offset,] zeilen]
        [PROCEDURE prozedur_name]
        [FOR UPDATE | LOCK IN SHARE MODE]]
@end example
@c help end

@code{SELECT} wird benutzt, um ausgewählte Zeilen aus einer oder mehreren
Tabellen abzurufen. @code{select_ausdruck} gibt die Spalten an, die Sie
abrufen wollen. @code{SELECT} kann auch benutzt werden, um Zeilen ohne
Bezug zu irgend einer Tabelle abzurufen. Beispiel:

@example
mysql> SELECT 1 + 1;
         -> 2
@end example

Alle benutzten Schlüsselwörter müssen genau in der oben angegebenen
Reihenfolge genannt werden. Beispielsweise muss eine @code{HAVING}-Klausel
nach jeglicher @code{GROUP BY}-Klausel und vor jeglicher @code{ORDER
BY}-Klausel kommen.

@itemize @bullet

@item
@cindex Aliase, für Ausdrücke
@cindex Ausdruck-Aliase
Einem @code{SELECT}-Ausdruck kann mit @code{AS} ein Alias zugewiesen
werden. Der Alias wird als Spaltenname verwendet und kann bei @code{ORDER
BY}- oder @code{HAVING}-Klauseln benutzt werden. Beispiel:

@example
mysql> select concat(nachname,', ',vorname) AS voller_name
    from tabelle ORDER BY voller_name;
@end example

@item
The @code{FROM tabellenreferenz}-Klausel gibt die Tabellen an, aus denen
Zeilen abgerufen werden sollen. Wenn Sie mehr als eine Tabelle aufführen,
führen Sie einen Join durch. Informationen über die Join-Syntax finden Sie
unter @ref{JOIN, , @code{JOIN}}.

@item
Sie können auf eine Spalte als @code{spalten_name} verweisen, als
@code{tabelle.spalten_name} oder als @code{datenbank.tabelle.spalten_name}.
Sie müssen das @code{tabelle}- oder @code{datenbank.tabelle}-Präfix für
einen Spaltenverweis in einem @code{SELECT}-Statement nicht angeben, es sei
denn, der Verweis wäre ansonsten mehrdeutig. Sie @ref{Legal names}; hier
finden sich Beispiele von Mehrdeutigkeit, die erfordern, dass Sie
ausführlichere Spaltenverweis-Formen benutzen.

@item
@cindex Aliase, für Tabellen
@cindex Tabellen-Aliase
Einem Tabellenverweis kann mit @code{tabelle [AS] alias_name} ein
Tabellen-Alias zugewiesen werden:

@example
mysql> select t1.name, t2.gehalt from angestellte AS t1, info AS t2
           where t1.name = t2.name;
mysql> select t1.name, t2.gehalt from angestellte t1, info t2
           where t1.name = t2.name;
@end example

@item
Auf Spalten, die für die Ausgabe ausgewählt wurden, kann in @code{ORDER
BY}- und @code{GROUP BY}-Klauseln mit Spaltennamen, Spalten-Aliasen oder
Spaltenpositionen verwiesen werden. Spaltenpositionen fangen mit 1 an:

@example
mysql> select hochschule, region, seed von tournament
           ORDER BY region, seed;
mysql> select hochschule, region AS r, seed AS s from turnier
           ORDER BY r, s;
mysql> select hochschule, region, seed from turnier
           ORDER BY 2, 3;
@end example

Um in absteigender Reihenfolge zu sortieren, fügen Sie dem Namen der
Spalte das @code{DESC}-Schlüsselwort in the @code{ORDER BY}-Klausel hinzu
(descending, absteigend), nach der Sie sortieren. Die Vorgabe ist
aufsteigende Reihenfolge. Das können Sie auch explizit angeben, indem Sie
das @code{ASC}-Schlüsselwort verwenden.

@item
In der @code{WHERE}-Klausel können Sie beliebige Funktionen verwenden, die
MySQL unterstützt. @xref{Functions}.

@item
Die @code{HAVING}-Klausel kann auf jede Spalte oder jeden Alias verweisen,
die bzw. der im @code{select_ausdruck} genannt wurde. Die Klausel wird
zuletzt angewandt, direkt bevor Ergebnisse an den Client geschickt werden,
ohne jede Optimierung. Benutzen Sie kein @code{HAVING} für Dinge, die in
der @code{WHERE}-Klausel stehen sollten. Schreiben Sie beispielsweise nicht
folgendes:

@example
mysql> select spalten_name from tabelle HAVING spalten_name > 0;
@end example

Sondern statt dessen:

@example
mysql> select spalten_name from tabelle WHERE spalten_name > 0;
@end example

Ab MySQL-Version 3.22.5 können Sie Anfragen auch wie folgt schreiben:

@example
mysql> select user,max(gehalt) from benutzer
           group by benutzer HAVING max(gehalt)>10;
@end example

In älteren MySQL-Versionen schreiben Sie statt dessen:

@example
mysql> select benutzer,max(gehalt) AS summe from benutzer
           group by benutzer HAVING summe>10;
@end example

@item
@code{SQL_SMALL_RESULT}, @code{SQL_BIG_RESULT}, @code{SQL_BUFFER_RESULT},
@code{STRAIGHT_JOIN} und @code{HIGH_PRIORITY} sind MySQL Erweiterungen zu
ANSI-SQL92.

@item
@code{HIGH_PRIORITY} gibt dem @code{SELECT} höhere Priorität als einem
Statement, das eine Tabelle aktualisiert. Sie sollten das nur für Anfragen
benutzen, die sehr schnell sind und sofort durchgeführt werden müssen. Eine
@code{SELECT HIGH_PRIORITY}-Anfrage läuft, wenn die Tabelle eine
Lese-Sperre hat, selbst wenn es ein Update-Statement gibt, das darauf
wartet, dass die Tabelle freigegeben wird.

@item
@code{SQL_BIG_RESULT} kann bei @code{GROUP BY} oder @code{DISTINCT} benutzt
werden, um dem Optimierer mitzuteilen, dass das Ergebnis sehr viele Zeilen
haben wird. In diesem Fall benutzt MySQL bei Bedarf direkt
Festplatten-basierende temporäre Tabellen. Ausserdem bevorzugt MySQL in
diesem Fall Sortieren vor dem Anlegen einer temporären Tabelle mit einem
Schlüssel auf den @code{GROUP BY}-Elementen.

@item
@cindex @code{GROUP BY}, Erweiterungen zu ANSI-SQL
Wenn Sie @code{GROUP BY} benutzen, werden die Ausgabe-Zeilen gemäß dem
@code{GROUP BY} sortiert, als hätten Sie ein @code{ORDER BY} für alle
Felder im @code{GROUP BY} angegeben. MySQL hat @code{GROUP BY} erweitert,
so dass Sie dafür auch @code{ASC} und @code{DESC} angeben können:

@example
SELECT a,COUNT(b) FROM tabelle GROUP BY a DESC
@end example

@item
MySQL hat die Benutzung von @code{GROUP BY} erweitert, um es Ihnen zu
gestatten, auch Felder auszuwählen, die nicht in der @code{GROUP
BY}-Klausel erwähnt wurden. Wenn Sie nicht die Ergebnisse erhalten, die Sie
von Ihrer Anfrage erwarten, lesen Sie bitte die @code{GROUP
BY}-Beschreibung.

@item
@cindex Hinweise
@code{SQL_BUFFER_RESULT} erzwingt, dass das Ergebnis in eine temporäre
Tabelle geschrieben wird. Das hilft MySQL, frühzeitig Tabellensperren
aufzuheben, und hilft in Fällen, in denen es lange dauert, das Ergebnis an
den Client zu senden.

@item
@cindex Hinweise
@code{SQL_SMALL_RESULT}, eine MySQL-spezifische Option, kann bei
@code{GROUP BY} oder @code{DISTINCT} benutzt werden, um dem Optimierer
mitzuteilen, dass der Ergebnissatz klein sein wird. In diesem Fall benutzt
MySQL schnelle temporäre Tabellen, um die Ergebnistabelle zu speichern,
anstatt Sortieren zu benutzen. In MySQL-Version 3.23 sollte das
normalerweise nicht benötigt werden.

@item
@cindex Hinweise
@code{STRAIGHT_JOIN} zwingt den Optimierer, Tabellen in der Reihenfolge zu
verknüpfen, in der sie in der @code{FROM}-Klausel aufgelistet sind. Sie
können das benutzen, um die Geschwindigkeit einer Anfrage zu erhöhen, wenn
der Optimierer Tabellen in nicht optimaler Reihenfolge verknüpft.
@xref{EXPLAIN, , @code{EXPLAIN}}.

@item
Die @code{LIMIT}-Klausel wird benutzt, um die Anzahl von Zeilen, die vom
@code{SELECT}-Statement zurückgegeben werden, zu beschränken. @code{LIMIT}
erwartet ein oder zwei numerische Argumente.

Wenn zwei Argumente angegeben sind, legt das erste den Offset der ersten
Zeile fest, die zurückgegeben wird, und das zweite gibt die maximale Anzahl
von Zeilen an, die zurückgegeben werden. Der Offset der anfänglichen Zeile
ist 0 (nicht 1):

@example
mysql> select * from tabelle LIMIT 5,10;  # Zeilen 6 bis 15 zurückgeben
@end example

Wenn ein Argument angegeben wird, stellt es die maximale Anzahl von Zeilen
dar, die zurückgegeben werden:

@example
mysql> select * from tabelle LIMIT 5;     # Die ersten 5 Zeilen zurückgeben
@end example

Mit anderen Worten ist @code{LIMIT n} äquivalent zu @code{LIMIT 0,n}.

@item
@tindex /etc/passwd
Die @code{SELECT ... INTO OUTFILE 'datei'}-Form von @code{SELECT} schreibt
die ausgewählten Zeilen in eine Datei. Die Datei wird auf dem Server-Host
erzeugt und darf nicht bereits bestehen (das verhindert unter anderem, dass
Datenbanktabellen und Dateien wie @file{/etc/passwd} zerstört werden). Sie
benötigen die @strong{file}-Berechtigung auf dem Server-Host, um diese Form
von @code{SELECT} auszuführen.

@code{SELECT ... INTO OUTFILE} ist hauptsächlich dafür vorgesehen, um eine
Tabelle auf der Server-Maschine schnell zu dumpen. Wenn Sie die
resultierende Datei auf einem anderen Host als dem Server-Host haben
wollen, können Sie @code{SELECT ... INTO OUTFILE} nicht benutzen. In diesem
Fall sollten Sie statt dessen ein Client-Programm wie @code{mysqldump
--tab} oder @code{mysql -e "SELECT ..." > outfile} benutzen, um die Datei
zu erzeugen.

@code{SELECT ...  INTO OUTFILE} ist das Komplement von @code{LOAD DATA
INFILE}; die Syntax für den @code{export_optionen}-Teil des Statements
besteht aus denselben @code{FIELDS}- und @code{LINES}-Klauseln, die beim
@code{LOAD DATA INFILE}-Statement benutzt werden. @xref{LOAD DATA, ,
@code{LOAD DATA}}.

In der resultierenden Textdatei werden nur folgende Zeichen durch das
@code{ESCAPED BY}-Zeichen escapet:

@itemize @bullet
@item Das @code{ESCAPED BY}-Zeichen
@item Das erste Zeichen in @code{FIELDS TERMINATED BY}
@item Das erste Zeichen in @code{LINES TERMINATED BY}
@end itemize

Zusätzlich wird @code{ASCII 0} in @code{ESCAPED BY}, gefolgt von 0
(@code{ASCII 48}), umgewandelt.

Der Grund hierfür ist, dass Sie jegliche @code{FIELDS TERMINATED BY}-,
@code{ESCAPED BY}- oder @code{LINES TERMINATED BY}-Zeichen escapen MÜSSEN,
um die Datei zuverlässig wieder einlesen zu können. @code{ASCII 0} wird
escapet, um das Lesen mit einigen Pagern zu erleichtern.

Weil sich die resultierende Datei nicht nach der SQL-Syntax richten muss,
muss nicht weiter escapet werden.

Im Folgenden ein Beispiel, wie man eine Datei in einem Format erhält, das
von vielen alten Programmen benutzt wird:

@example
SELECT a,b,a+b INTO OUTFILE "/tmp/resultat.text"
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY "\n"
FROM tabelle;
@end example

@item
@findex DUMPFILE
Wenn Sie @code{INTO DUMPFILE} anstelle von @code{INTO OUTFILE} benutzen,
schreibt MySQL nur eine Zeile in die Datei, ohne jede Spalten- oder
Zeilen-Begrenzer und ohne jedes Escapen. Das ist nützlich, wenn Sie ein
Blob in eine Datei speichern wollen.

@item
Beachten Sie, dass jede Datei, die von @code{INTO OUTFILE} und @code{INTO
DUMPFILE} erzeugt wird, für alle Benutzer lesbar ist! Der Grund liegt
darin, dass der MySQL-Server keine Datei erzeugen kann, die jemandem
anderen gehört als dem Benutzer, unter dem er läuft (Sie sollten
@code{mysqld} nie als Root laufen lassen), daher muss die Datei für
jedermann lesbar sein, damit Sie die Zeilen abrufen können.

@item
Wenn Sie @code{FOR UPDATE} bei einem Tabellen-Handler mit
Seiten-/Zeilen-Sperren benutzen, werden die untersuchten Zeilen
schreib-gesperrt.
@end itemize



@menu
* JOIN::                        
* UNION::                       
@end menu

@node JOIN, UNION, SELECT, SELECT
@c German node JOIN
@subsubsection @code{JOIN}-Syntax

@findex JOIN
@findex INNER JOIN
@findex CROSS JOIN
@findex LEFT JOIN
@findex LEFT OUTER JOIN
@findex NATURAL LEFT JOIN
@findex NATURAL LEFT OUTER JOIN
@findex RIGHT JOIN
@findex RIGHT OUTER JOIN
@findex NATURAL RIGHT JOIN
@findex NATURAL RIGHT OUTER JOIN
@findex STRAIGHT_JOIN

MySQL unterstützt folgende @code{JOIN}-Syntaxen für
@code{SELECT}-Statements:

@example
tabellen_verweis, tabellen_verweis
tabellen_verweis [CROSS] JOIN tabellen_verweis
tabellen_verweis INNER JOIN tabellen_verweis join_bedingung
tabellen_verweis STRAIGHT_JOIN tabellen_verweis
tabellen_verweis LEFT [OUTER] JOIN tabellen_verweis join_bedingung
tabellen_verweis LEFT [OUTER] JOIN tabellen_verweis
tabellen_verweis NATURAL [LEFT [OUTER]] JOIN tabellen_verweis
@{ oder tabellen_verweis LEFT OUTER JOIN tabellen_verweis ON bedingungs_ausdruck @}
tabellen_verweis RIGHT [OUTER] JOIN tabellen_verweis join_bedingung
tabellen_verweis RIGHT [OUTER] JOIN tabellen_verweis
tabellen_verweis NATURAL [RIGHT [OUTER]] JOIN tabellen_verweis
@end example

Wobei @code{tabellen_verweis} definiert ist als:
@example
tabelle [[AS] alias] [USE INDEX (schluessel_liste)] [IGNORE INDEX (schluessel_liste)]
@end example

Und @code{join_bedingung} definiert ist als:

@example
ON bedingungs_ausdruck |
USING (spalten_liste)
@end example

Sie sollten nie irgend welche Bedingungen im @code{ON}-Teil haben, die dazu
benutzt werden, um die Zeilen, die im Ergebnissatz auftauchen, zu
beschränken. Wenn Sie so etwas tun wollen, müssen Sie das in der
@code{WHERE}-Klausel tun.

Beachten Sie, dass vor Version 3.23.17 @code{INNER JOIN} keine
@code{join_bedingung} aufnahm!

@cindex ODBC-Kompatibilität
@cindex Kompatibilität, mit ODBC
Die letzte oben dargestellte @code{LEFT OUTER JOIN}-Syntax gibt es nur aus
Gründen der Kompatibilität mit ODBC:

@itemize @bullet
@item
Einem Tabellenverweis kann mit @code{tabelle AS alias_name} oder
@code{tabelle alias_name} ein Alias zugewiesen werden:

@example
mysql> select t1.name, t2.gehalt from angestellte AS t1, info AS t2
           where t1.name = t2.name;
@end example

@item
Der @code{ON}-Bedingungscode ist jeglicher Bedingungscode der Form, wie er
auch in einer @code{WHERE}-Klausel benutzt werden kann.

@item
Wenn es für die rechte Tabelle keinen übereinstimmenden Datensatz im
@code{ON}- oder @code{USING}-Teil eines @code{LEFT JOIN} gibt, wird für die
rechte Tabelle eine Zeile benutzt, in der alle Spalten auf @code{NULL}
gesetzt sind. Das können Sie benutzen, um Datensätze in einer Tabelle
herauszusuchen, die in einer anderen Tabelle kein Gegenstück haben:

@example
mysql> select tabelle1.* from tabelle1
           LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id
           where tabelle2.id is NULL;
@end example

Dieses Beispiel findet alle Zeilen in @code{tabelle1} mit einem
@code{id}-Wert, der in @code{tabelle2} nicht vorhanden ist (also alle
Zeilen in @code{tabelle1} ohne entsprechende Zeile in @code{tabelle2}).
Hierbei wird natürlich angenommen, dass @code{tabelle2.id} als @code{NOT
NULL} deklariert ist. @xref{LEFT JOIN optimisation}.

@item
Die @code{USING}-@code{(spalten_liste)}-Klausel nennt eine Auflistung von
Spalten, die in beiden Tabellen existieren müssen. Eine
@code{USING}-Klausel wie:

@example
A LEFT JOIN B USING (C1,C2,C3,...)
@end example

Ist definiert als semantisch identisch mit einem @code{ON}-Ausdruck wie
diesem:

@example
A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
@end example

@item
Der @code{NATURAL [LEFT] JOIN} zweier Tabellen ist definiert als semantisch
identisch äquivalent zu einem @code{INNER JOIN} oder einem @code{LEFT JOIN}
mit einer @code{USING}-Klausel, die alle Spalten nennt, die in beiden
Tabellen existieren.

@item
@code{RIGHT JOIN} funktioniert analog wie @code{LEFT JOIN}. Um Code
zwischen Datenbanken portabel zu halten, wird empfohlen, @code{LEFT JOIN}
anstelle von @code{RIGHT JOIN} zu benutzen.

@item
@cindex Hinweise
@code{STRAIGHT_JOIN} ist identisch mit @code{JOIN}, ausser dass die linke
Tabelle immer vor der rechten Tabelle gelesen wird. Das kann in den
(wenigen) Fällen benutzt werden, wo der Optimierer die Tabellen in die
falsche Reihenfolge bringt.

@item
@cindex Hinweise
Ab MySQL-Version 3.23.12 können Sie Hinweise darüber geben, welchen Index
MySQL benutzen sollte, wenn Informationen aus einer Tabelle abgerufen
werden. Das ist nützlich, wenn @code{EXPLAIN} zeigt, dass MySQL den
falschen Index benutzt. Indem Sie @code{USE INDEX (schluessel_liste)}
angeben, können Sie MySQL anweisen, nur einen der angegebenen Indexe zu
benutzen, um Zeilen in der Tabelle zu finden. Die alternative Syntax
@code{IGNORE INDEX (schluessel_liste)} kann benutzt werden, um MySQL
anzuweisen, einen bestimmten Index nicht zu benutzen.
@end itemize

Einige Beispiele:

@example
mysql> select * from tabelle1,tabelle2 where tabelle1.id=tabelle2.id;
mysql> select * from tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id;
mysql> select * from tabelle1 LEFT JOIN tabelle2 USING (id);
mysql> select * from tabelle1 LEFT JOIN tabelle2 ON tabelle1.id=tabelle2.id
           LEFT JOIN table3 ON tabelle2.id=table3.id;
mysql> select * from tabelle1 USE INDEX (schluessel1,schluessel2) WHERE schluessel1=1 und schluessel2=2 AND
       schluessel3=3;
mysql> select * from tabelle1 IGNORE INDEX (schluessel3) WHERE schluessel1=1 und schluessel2=2 AND
       schluessel3=3;
@end example

@xref{LEFT JOIN optimisation, , @code{LEFT JOIN}-Optimierung}.


@node UNION,  , JOIN, SELECT
@c German node UNION
@subsubsection @code{UNION}-Syntax

@findex UNION

@example
SELECT ....
UNION [ALL]
SELECT ....
  [UNION 
   SELECT ...]
@end example

@code{UNION} ist implementiert in MySQL 4.0.0.

@code{UNION} wird benutzt, um das Ergebnis vieler @code{SELECT}-Statements
in einem Ergebnissatz zu kombinieren.

Die @code{SELECT}-Befehle sind normale SELECT-Befehle, aber mit folgenden
Einschränkungen:

@itemize @bullet
@item
Nur der letzte @code{SELECT}-Befehl darf @code{INTO OUTFILE} enthalten.
@item
Nur der letzte @code{SELECT}-Befehl darf @code{ORDER BY} enthalten.
@end itemize

Wenn Sie das Schlüsselwort @code{ALL} für @code{UNION} nicht benutzen, sind
alle zurückgegebenen Zeilen eindeutig (unique), als hätten Sie ein
@code{DISTINCT} für den gesamten Ergebnissatz gemacht. Wenn Sie @code{ALL}
angeben, erhalten Sie alle übereinstimmenden Zeilen von allen benutzten
@code{SELECT}-Statements.

@node HANDLER, INSERT, SELECT, Data Manipulation
@c German node INSERT
@subsection @code{INSERT}-Syntax

@findex INSERT

@example
    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tabelle [(spalten_name,...)]
        VALUES (ausdruck,...),(...),...
oder  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tabelle [(spalten_name,...)]
        SELECT ...
oder  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tabelle
        SET spalten_name=ausdruck, spalten_name=ausdruck, ...

@end example

@code{INSERT} fügt neue Zeilen in eine bestehende Tabelle ein. Die
@code{INSERT ... VALUES}-Form des Statements fügt Zeilen basierend auf
explizit angegebenen Werten ein. Die @code{INSERT ... SELECT}-Form fügt
Zeilen ein, die aus einer oder mehreren anderen Tabellen ausgewählt wurden.
Die @code{INSERT ... VALUES}-Form mit mehrfachen Wertelisten wird ab
MySQL-Version 3.22.5 unterstützt. Die @code{spalten_name=expression}-Syntax
wird ab MySQL-Version 3.22.10 unterstützt.

@code{tabelle} ist die Tabelle, in die Zeilen eingefügt werden sollen. Die
Spaltennamenliste oder die @code{SET}-Klausel geben an, für welche Spalten
das Statement Werte angibt:

@itemize @bullet
@item
Wenn Sie keine Spaltenliste für @code{INSERT ... VALUES} oder @code{INSERT
... SELECT} angeben, müssen für alle Spalten Werte in der
@code{VALUES()}-Liste oder vom @code{SELECT} bereit stehen. Wenn Sie die
Reihenfolge der Tabellenspalten nicht kennen, benutzen Sie @code{DESCRIBE
tabelle}, um sie herauszufinden.

@item
Jede Spalte, die nicht explizit in einer Werteliste angegeben wird, wird
auf ihren Vorgabewert gesetzt. Wenn Sie beispielsweise eine Spaltenliste
angeben, die nicht alle Tabellenspalten nennt, werden unbenannte Spalten
auf ihre Vorgabewerte gesetzt. Die Zuweisung von Vorgabewerten ist in
@ref{CREATE TABLE, , @code{CREATE TABLE}} beschrieben.

@item
Ein @code{ausdruck} kann sich auf jede Spalte beziehen, die vorher in einer
Werteliste angegeben wurde. Beispielsweise können Sie folgendes eingeben:

@example
mysql> INSERT INTO tabelle (spalte1,spalte2) VALUES(15,spalte1*2);
@end example

Aber nicht das hier:

@example
mysql> INSERT INTO tabelle (spalte1,spalte2) VALUES(spalte2*2,15);
@end example

@item
Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird die Ausführung
von @code{INSERT} verzögert, bis kein anderer Client mehr aus der Tabelle
liest. In diesem Fall muss der Client warten, bis das INSERT-Statement
fertig ist, was lange Zeit dauern kann, wenn die Tabelle stark benutzt
wird. Das ist im Gegensatz zu @code{INSERT DELAYED}, was den Client sofort
weitermachen läßt. @xref{INSERT DELAYED}. Beachten Sie, dass
@code{LOW_PRIORITY} normalerweise nicht bei @code{MyISAM}-Tabellen benutzt
werden sollte, weil dadurch gleichzeitige Einfügeoperationen verhindert
werden. @xref{MyISAM}.

@item
Wenn Sie das Schlüsselwort @code{IGNORE} in einem @code{INSERT} mit vielen
Wertezeilen angeben, werden alle Zeilen, die einen bestehenden
@code{PRIMARY}- oder @code{UNIQUE}-Schlüssel duplizieren würden, ignoriert
und nicht eingefügt. Wenn Sie @code{IGNORE} nicht angeben, wird die
Einfügeoperation abgebrochen, wenn es eine Zeile gibt, die einen
bestehenden Schlüsselwert duplizieren würde. Mit der C-API-Funktion
@code{mysql_info()} können Sie feststellen, wie viele Zeilen in die Tabelle
eingefügt wurden.

@item
Wenn MySQL mit der @code{DONT_USE_DEFAULT_FIELDS}-Option konfiguriert
wurde, erzeugen @code{INSERT}-Statements einen Fehler, wenn Sie nicht
explizit Werte für alle Spalten angeben, die einen Nicht-@code{NULL}-Wert
erfordern. @xref{configure options,  , @code{configure}-Optionen}.

@item
Den Wert, der für eine @code{AUTO_INCREMENT}-Spalte benutzt wurde, finden
Sie mit der @code{mysql_insert_id}-Funktion heraus. @xref{mysql_insert_id,
, @code{mysql_insert_id()}}.
@end itemize

@findex mysql_info()
Wenn Sie ein @code{INSERT ... SELECT}- oder ein @code{INSERT ...
VALUES}-Statement mit mehrfachen Wertlisten benutzen, können Sie die
C-API-Funktion @code{mysql_info()} benutzen, um Informationen über die
Anfrage zu erhalten. Das Format der Informationszeichenkette ist unten
dargestellt:

@example
Records: 100 Duplicates: 0 Warnings: 0
@end example

@code{Duplicates} zeigt die Anzahl von Zeilen, die nicht eingefügt werden
konnten, weil sie einen bestehenden eindeutigen Indexwert dupliziert
hätten. @code{Warnings} zeigen die Anzahl von Versuchen, Spaltenwerte
einzufügen, die in irgend einer Weise problematisch waren. Warnungen
erfolgen unter folgenden Umständen:

@itemize @bullet
@item
Wenn @code{NULL} in eine Spalte eingefügt wird, die als @code{NOT NULL}
deklariert ist. Die Spalte wird auf ihren Vorgabewert gesetzt.

@item
Wenn eine numerische Spalte auf einen Wert ausserhalb des Wertebereichs der
Spalte gesetzt wird. Der Wert wird auf den entsprechenden Endpunkt des
Bereichs abgeschnitten.

@item
Wenn eine numerische Spalte auf einen Wert wie @code{'10.34 a'} gesetzt
wird. Die unsinnigen Zeichen am Ende werden entfernt und der verbleibende
numerische Anteil eingefügt. Wenn der Wert als Zahl überhaupt keinen Sinn
ergibt, wird die Spalte auf @code{0} gesetzt.

@item
Wenn eine Zeichenkette in eine @code{CHAR}-, @code{VARCHAR}-, @code{TEXT}-
oder @code{BLOB}-Spalte eingefügt wird, die die maximale Länge der Spalte
überschreitet. Der Wert wird auf die maximale Spaltenlänge beschnitten.

@item
Wenn ein Wert in eine DATE- oder TIME-Spalte eingefügt wird, der für den
Spaltentyp nicht zulässig ist. Die Spalte wird auf den entsprechenden
0-Wert für diesen Typ gesetzt.
@end itemize

@findex HANDLER
@node INSERT, INSERT DELAYED, HANDLER, Data Manipulation
@c German node HANDLER
@subsection @code{HANDLER}-Syntax

@example
HANDLER tabelle OPEN [ AS alias ]
HANDLER tabelle READ index @{ = | >= | <= | < @} (wert1, wert2, ... )  [ WHERE ... ] [LIMIT ... ]
HANDLER tabelle READ index @{ FIRST | NEXT | PREV | LAST @} [ WHERE ... ] [LIMIT ... ]
HANDLER tabelle READ @{ FIRST | NEXT @}  [ WHERE ... ] [LIMIT ... ]
HANDLER tabelle CLOSE
@end example

Das @code{HANDLER}-Statement ermöglicht direkten Zugriff auf die
MySQL-Tabellenschnittstelle unter Umgehung des SQL-Optimierers. Daher ist
es schneller als SELECT.

Die erste Form des @code{HANDLER}-Statements öffnet eine Tabelle und macht
sie über die folgenden @code{HANDLER ... READ}-Routinen zugänglich. Dieses
Tabellenobjekt wird nicht mit anderen Threads geteilt und wird nicht
geschlossen, bis der Thread @code{HANDLER tabelle CLOSE} aufruft oder
stirbt.

Die zweite Form holt eine (oder mehrere, festgelegt durch die
@code{LIMIT}-Klausel) Zeile, bei der der angegebene Index mit der Bedingung
übereinstimmt und die @code{WHERE}-Bedingung erfüllt ist. Wenn der Index
aus mehreren Teilen besteht (also mehrere Spalten überspannt), werden die
Werte in einer Komma-getrennten Liste angegeben, wobei es möglich ist, nur
Werte für einige erste Spalten anzugeben.

Die dritte Form holt eine (oder mehrere, festgelegt durch die
@code{LIMIT}-Klausel) Zeile in Index-Reihenfolge aus der Tabelle, bei der
die @code{WHERE}-Bedingung erfüllt ist.

Die vierte Form (ohne Index-Angabe) holt eine (oder mehrere, festgelegt
durch die @code{LIMIT}-Klausel) Zeile in natürlicher Zeilenreihenfolge aus
der Tabelle (wie in der Daten-Datei gespeichert), bei der die
@code{WHERE}-Bedingung erfüllt ist. Das ist schneller als @code{HANDLER
tabelle READ index}, wenn ein kompletter Tabellen-Scan erwünscht ist.

Die letzte Form schließt eine mit @code{HANDLER ... OPEN} geöffnete
Tabelle.

@code{HANDLER} ist in gewisser Hinsicht ein Statement auf niedriger Ebene
(Low-Level), dass zum Beispiel keine Konsistenz gewährleistet. Das heißt,
@code{HANDLER ... OPEN} nimmt @strong{KEINEN} Schnappschuss der Tabelle auf
und sperrt die Tabelle @strong{NICHT}. Das bedeutet, dass nach
@code{HANDLER ... OPEN} Tabellendaten verändert werden können (durch diesen
oder einen anderen Thread) und dass diese Veränderungen nur teilweise in
@code{HANDLER ... NEXT}- oder @code{HANDLER ... PREV}-Scans erscheinen.




@findex REPLACE ... SELECT
@findex INSERT ... SELECT



@menu
* INSERT SELECT::               
@end menu

@node INSERT SELECT,  , INSERT, INSERT
@c German node INSERT SELECT
@subsubsection @code{INSERT ... SELECT}-Syntax

@example
INSERT [LOW_PRIORITY] [IGNORE] [INTO] tabelle [(spalten_liste)] SELECT ...
@end example

Mit dem @code{INSERT ... SELECT}-Statement können Sie schnell viele Zeilen
aus einer oder mehreren anderen Tabellen einfügen.

@example
INSERT INTO temporaere_tabelle2 (fldID) SELECT temporaere_tabelle1.fldOrder_ID FROM temporaere_tabelle1 WHERE
temporaere_tabelle1.fldOrder_ID > 100;
@end example

Folgende Bedingungen gelten für ein @code{INSERT ... SELECT}-Statement:

@c German FIX changed all @Minus to @minus
@itemize @minus
@item
Die Ziel-Tabelle des @code{INSERT}-Statements darf nicht in der
@code{FROM}-Klausel des @code{SELECT}-Teils der Anfrage erscheinen, weil es
in ANSI-SQL verboten ist, aus derselben Tabelle auszuwählen
(@code{SELECT}), in die eingefügt wird. (Das Problem liegt darin, dass das
@code{SELECT} möglicherweise Datensätze finden würde, die früher während
desselben Laufs eingefügt wurden. Wenn man Sub-Select-Klauseln verwendet,
könnte die Situation schnell sehr verwirrend werden!)

@item
@code{AUTO_INCREMENT}-Spalten funktionieren wie gehabt.

@item
Sie können die C-API-Funktion @code{mysql_info()} benutzen, um
Informationen über die Anfrage zu erhalten. @xref{INSERT}.

@item
Um sicherzustellen, dass die Update-Log-Datei/Binär-Log-Datei benutzt
werden kann, um die Original-Tabellenlänge neu zu erzeugen, läßt MySQL
während @code{INSERT .... SELECT} keine gleichzeitigen Einfügeoperationen
zu.
@end itemize

Sie können natürlich @code{REPLACE} anstelle von @code{INSERT} benutzen, um
alte Zeilen zu überschreiben.


@node INSERT DELAYED, UPDATE, INSERT, Data Manipulation
@c German node INSERT DELAYED
@subsection @code{INSERT DELAYED}-Syntax

@findex INSERT DELAYED
@findex DELAYED

@cindex INSERT DELAYED

@example
INSERT DELAYED ...
@end example

Die @code{DELAYED}-Option für das @code{INSERT}-Statement ist eine
MySQL-spezifische Option, die sehr nützlich ist, wenn Sie Clients haben,
die nicht warten können, bis das @code{INSERT} fertig ist. Die ist ein
häufiges Problem, wenn Sie MySQL zum Loggen benutzen und gelegentlich
@code{SELECT}- und @code{UPDATE}-Statements laufen lassen, die lange Zeit
benötigen. @code{DELAYED} wurde in MySQL-Version 3.22.15 eingeführt. Es ist
eine MySQL Erweiterung zu ANSI-SQL92.

@code{INSERT DELAYED} funktioniert nur bei @code{ISAM}- und
@code{MyISAM}-Tabellen. Beachten Sie: Weil @code{MyISAM}-Tabellen
gleichzeitige @code{SELECT} und @code{INSERT} unterstützen, wenn es keine
freien Blöcke mitten in der Daten-Datei gibt, müssen Sie @code{INSERT
DELAYED} bei @code{MyISAM} nur sehr selten benutzen. @xref{MyISAM}.

Wenn Sie @code{INSERT DELAYED} benutzen, erhält der Client sofort ein Okay,
und die Zeile wird eingefügt, wenn die Tabelle nicht mehr durch einen
anderen Thread in Benutzung ist.

Ein weiterer großer Vorteil von @code{INSERT DELAYED} ist, dass
Einfügeoperationen vieler Clients gebündelt und in einem Block geschrieben
werden. Das ist viel schneller als viele separate Inserts durchzuführen.

Beachten Sie, dass momentan die Zeilen in der Warteschlange solange nur im
Arbeitsspeicher gehalten werden, bis sie in die Tabelle eingefügt sind. Das
heißt, wenn Sie @code{mysqld} auf die harte Tour killen (@code{kill -9})
oder wenn @code{mysqld} unerwartet stirbt, sind Zeilen in der
Warteschlange, die noch nicht auf Festplatte geschrieben wurden, verloren!

Im Folgenden ist detailliert beschrieben, was geschieht, wenn Sie die
@code{DELAYED}-Option für @code{INSERT} oder @code{REPLACE} benutzen. In
dieser Beschreibung ist der ``Thread'' der Thread, der einen @code{INSERT
DELAYED}-Befehl empfängt. ``Handler'' ist der Thread, der alle @code{INSERT
DELAYED}-Statements für ein bestimmte Tabelle handhabt.

@itemize @bullet
@item
When ein Thread ein @code{DELAYED}-Statement für eine Tabelle ausführt,
wird ein Handler-Thread erzeugt, um alle @code{DELAYED}-Statements für die
Tabelle auszuführen, wenn ein solcher Handler nicht schon existiert.

@item
Der Thread prüft, ob der Handler bereit eine @code{DELAYED}-Sperre erhalten
hat oder nicht. Wenn nicht, weist es den Handler-Thread an, das zu tun. Die
@code{DELAYED}-Sperre kann selbst dann erlangt werden, wenn ein anderer
Thread eine @code{READ}- oder @code{WRITE}-Sperre auf der Tabelle hat. Der
Handler wartet jedoch auf alle @code{ALTER TABLE}-Sperren oder @code{FLUSH
TABLES}, um sicherzustellen, dass die Tabellenstruktur aktuell ist.

@item
Der Thread führt das @code{INSERT}-Statement aus, aber statt die Zeile in
die Tabelle zu schreiben stellt er eine Kopie der endgültigen Zeile in eine
Warteschlange, die vom Handler-Thread verwaltet wird. Alle Syntaxfehler
werden vom Thread erkannt und dem Client-Programm mitgeteilt.

@item
Der Client kann die Anzahl von Duplikaten oder den
@code{AUTO_INCREMENT}-Wert für die resultierende Zeile nicht mitteilen. Er
kann Sie vom Server nicht erhalten, weil das @code{INSERT} zurückkehrt,
bevor die Einfügeoperation fertig ist. Wenn Sie die C-API benutzen, gibt
die @code{mysql_info()}-Funktion aus demselben Grund nichts Sinnvolles
zurück.

@item
Die Update-Log-Datei wird vom Handler-Thread aktualisiert, wenn die Zeile
in die Tabelle eingefügt wird. Im Falle des Einfügens mehrerer Zeilen wird
die Update-Log-Datei aktualisiert, wenn die erste Zeile eingefügt wird.

@item
Nachdem alle @code{delayed_insert_limit} Zeilen geschrieben wurden, prüft
der Handler, ob noch irgend welche @code{SELECT}-Statements anhängig sind
oder nicht. Falls ja, gestattet er diesen, ausgeführt zu werden, bevor
weiter gemacht wird.

@cindex delayed_insert_limit
@cindex timeout
@item
Wenn der Handler keine Zeilen mehr in seiner Warteschlange hat, wird die
Tabellensperre aufgehoben. Wenn innerhalb von @code{delayed_insert_timeout}
Sekunden keine neuen @code{INSERT DELAYED}-Befehle mehr empfangen werden,
beendet sich der Handler.

@item
Wenn mehr als @code{delayed_queue_size} Zeilen bereits in einer bestimmten
Handler-Warteschlange anhängig sind, wartet der Thread, der nach
@code{INSERT DELAYED} anfragt, bis es wieder Platz in der Warteschlange
gibt. Damit wird sichergestellt, dass der @code{mysqld}-Server nicht den
gesamten Arbeitsspeicher für die DELAYED-Warteschlange verbraucht.

@item
Der Handler-Thread zeigt sich in der MySQL-Prozessliste mit
@code{delayed_insert} in der @code{Command}-Spalte. Er wird gekillt, wenn
Sie einen @code{FLUSH TABLES}-Befehl ausführen oder ihn mit @code{KILL
Thread_id} killen. Er wird jedoch zuerst alle Zeilen in der Warteschlange
in die Tabelle schreiben, bevor er sich beendet. Während dieser Zeit
akzeptiert er keine neuen @code{INSERT}-Befehle von anderen Threads mehr.
Wenn Sie danach einen @code{INSERT DELAYED}-Befehl ausführen, wird ein
neuer Handler-Thread erzeugt.

@item
Beachten Sie, dass oben Gesagtes bedeutet, dass @code{INSERT
DELAYED}-Befehle höhere Priorität haben als normale @code{INSERT}-Befehle,
wenn es einen @code{INSERT DELAYED}-Handler gibt, der bereits läuft!
Andere Aktualisierungsbefehle müssen warten, bis die @code{INSERT
DELAYED}-Warteschlange leer ist, jemand den Handler-Thread killt (mit
@code{KILL Thread_id}) oder jemand @code{FLUSH TABLES} ausführt.

@item
Die folgenden Status-Variablen stellen Informationen über @code{INSERT
DELAYED}-Befehle bereits:

@multitable @columnfractions .35 .65
@item @strong{Variable} @tab @strong{Bedeutung}
@item @code{Delayed_insert_thread} @tab Nummer des Handler-Threads
@item @code{Delayed_writes} @tab Anzahl der Zeilen, die mit @code{INSERT DELAYED} geschrieben wurden
@item @code{Not_flushed_delayed_rows} @tab Anzahl der Zeilen, die darauf warten, geschrieben zu werden
@end multitable

Sie können diese Variablen betrachten, wenn Sie ein @code{SHOW
STATUS}-Statement oder einen @code{mysqladmin extended-status}-Befehl
ausführen.
@end itemize

Beachten Sie, dass @code{INSERT DELAYED} langsamer ist als ein normales
INSERT, wenn die Tabelle nicht in Benutzung ist. Ausserdem gibt es einen
zusätzlichen Overhead für den Server, um einen separaten Thread für jede
Tabelle zu handhaben, für die Sie @code{INSERT DELAYED} benutzen. Das
heißt, Sie sollten @code{INSERT DELAYED} nur benutzen, wenn Sie es
wirklich benötigen!


@node UPDATE, DELETE, INSERT DELAYED, Data Manipulation
@c German node UPDATE
@subsection @code{UPDATE}-Syntax

@findex UPDATE

@example
UPDATE [LOW_PRIORITY] [IGNORE] tabelle
    SET spalten_name1=ausdruck1, [spalten_name2=ausdruck2, ...]
    [WHERE where_definition]
    [LIMIT #]
@end example

@code{UPDATE} aktualisiert Spalten in bestehenden Tabellenzeilen mit neuen
Werten. Die @code{SET}-Klausel gibt an, welche Spalten geändert werden
sollen und welche Werte ihnen zugewiesen werden. Die @code{WHERE}-Klausel
legt - falls angegeben - fest, welche Zeilen aktualisiert werden sollen.
Ansonsten werden alle Zeile aktualisiert. Wenn die @code{ORDER BY}-Klausel
angegeben ist, werden die Zeilen in der angegebenen Reihenfolge
aktualisiert.

Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird die Ausführung
von @code{UPDATE} verzögert, bis keine anderen Clients mehr aus der Tabelle
lesen.

Wenn Sie das Schlüsselwort @code{IGNORE} angeben, bricht das
UPDATE-Statement nicht ab, selbst wenn während der Aktualisierung Fehler
wegen doppelter Schlüsseleinträge auftreten. Zeilen, die Konflikte
verursachen würden, werden nicht aktualisiert.

Wenn Sie auf eine Spalte von @code{tabelle} in einem Ausdruck zugreifen,
benutzt @code{UPDATE} den momentanen Wert der Spalte. Folgendes Statement
zum Beispiel setzt die @code{age}-Spalte auf ihren momentanen Wert plus 1:

@example
mysql> UPDATE personen SET age=age+1;
@end example

@code{UPDATE}-Zuweisungen werden von links nach rechts ausgewertet.
Folgendes Statement zum Beispiel verdoppelt die @code{age}-Spalte und
inkrementiert sie danach:

@example
mysql> UPDATE personen SET age=age*2, age=age+1;
@end example

Wenn Sie eine Spalte auf einen Wert setzen, den sie momentan besitzt,
erkennt MySQL dies und aktualisiert sie nicht.

@findex mysql_info()
@code{UPDATE} gibt die Anzahl von Zeilen zurück, die tatsächlich geändert
wurden. Ab MySQL-Version 3.22 gibt die C-API-Funktion @code{mysql_info()}
die Anzahl von Zeilen zurück, die übereinstimmten und aktualisiert wurden,
und die Anzahl von Warnungen, die während @code{UPDATE} geschahen.

In MySQL-Version 3.23 können Sie @code{LIMIT #} benutzen, um
sicherzustellen, dass nur eine angegebene Anzahl von Zeilen geändert wird.


@node DELETE, TRUNCATE, UPDATE, Data Manipulation
@c German node DELETE
@subsection @code{DELETE}-Syntax

@findex DELETE

@example
DELETE [LOW_PRIORITY | QUICK] FROM tabelle
    [WHERE where_definition]
    [ORDER BY ...]
    [LIMIT zeilen]

oder

DELETE [LOW_PRIORITY | QUICK] tabelle[.*] [tabelle[.*] ...] FROM
tabellenverweis [WHERE where_definition]
@end example

@code{DELETE} löscht Zeilen aus @code{tabelle}, die mit der in
@code{where_definition} angegebenen Bedingung übereinstimmen, und gibt die
Anzahl der gelöschten Datensätze zurück.

Wenn Sie @code{DELETE} ohne @code{WHERE}-Klausel angeben, werden alle
Zeilen gelöscht. Wenn Sie das im @code{AUTOCOMMIT}-Modus machen,
funktioniert es wie @code{TRUNCATE}. @xref{TRUNCATE}. In MySQL 3.23 gibt
@code{DELETE} ohne eine @code{WHERE}-Klausel als Anzahl von betroffenen
Datensätzen 0 zurück.

Wenn Sie wissen wollen, wie viele Datensätze tatsächlich gelöscht wurden,
wenn Sie alle Zeilen löschen, und eine Geschwindigkeitseinbusse in Kauf
nehmen, können Sie ein @code{DELETE}-Statement folgender Form eingeben:

@example
mysql> DELETE FROM tabelle WHERE 1>0;
@end example

Beachten Sie, dass das VIEL langsamer als @code{DELETE FROM tabelle} ohne
@code{WHERE}-Klausel ist, weil es Zeilen eine nach der anderen löscht.

Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird die Ausführung
von @code{DELETE} verzögert, bis kein anderer Client mehr aus der Tabelle
liest.

Wenn Sie das Wort @code{QUICK} angeben, fasst der Tabellen-Handler während
des Löschvorgangs keine Index-Blätter (Index Leafs) zusammen, was bestimmte
Arten von Löschvorgängen beschleunigen kann.

In MyISAM-Tabellen werden gelöschte Datensätze in einer verknüpften Liste
verwaltet und nachfolgende @code{INSERT}-Operationen benutzen alte
Datensatzpositionen neu. Um unbenutzten Platz freizugeben und Dateigrößen
zu verringern, benutzen Sie das @code{OPTIMIZE TABLE}-Statement oder das
@code{myisamchk}-Dienstprogramm, um die Tabellen neu zu organisieren.
@code{OPTIMIZE TABLE} ist einfacher, aber @code{myisamchk} ist schneller.
Siehe @ref{OPTIMIZE TABLE, , @code{OPTIMIZE TABLE}} und @ref{Optimisation}.

Das Multi-Tabellen-Löschformat wird ab MySQL 4.0.0 unterstützt.

Die Idee ist, dass nur übereinstimmende Zeilen aus den Tabellen, die VOR
der @code{FROM}-Klausel stehen, gelöscht werden. Die Auswirkung ist, dass
Sie Zeilen aus vielen Tabellen zugleich löschen können, sowie dass
zusätzliche Tabellen zum Suchen benutzt werden.

Das @code{.*}-Zeichen nach den Tabellennamen ist nur aus Gründen der
Kompatibilität mit @code{Access} vorhanden:

@example
DELETE t1,t2 FROM t1,t2,t3 WHERE t1.id=t2.id AND t2.id=t3.id
@end example

In diesem Fall werden übereinstimmende Zeilen nur aus den Tabellen
@code{t1} und @code{t2} gelöscht.

@code{ORDER BY} und Benutzung mehrfacher Tabellen bei DELETE wird in MySQL
4.0 unterstützt.

Wenn eine @code{ORDER BY}-Klausel benutzt wird, werden die Zeilen in dieser
Reihenfolge gelöscht. Das ist nur in Verbindung mit @code{LIMIT} wirklich
sinnvoll. Beispiel:

@example
DELETE FROM logdatei
WHERE user = 'jcole'
ORDER BY zeitstempel
LIMIT 1
@end example

Das löscht den ältesten Eintrag (von @code{zeitstempel}), wo die Zeile mit
der @code{WHERE}-Klausel übereinstimmt.

Die MySQL-spezifische @code{LIMIT rows}-Option für @code{DELETE} weist den
Server an, welche maximale Anzahl von Zeilen gelöscht wird, bevor die
Kontrolle an den Client zurück gegeben wird. Das kann benutzt werden um
sicherzustellen, dass ein bestimmter @code{DELETE}-Befehl nicht zu viel
Zeit beansprucht. Sie können den @code{DELETE}-Befehl einfach wiederholen,
bis die Anzahl betroffener Zeilen kleiner ist als der @code{LIMIT}-Wert.


@node TRUNCATE, REPLACE, DELETE, Data Manipulation
@c German node TRUNCATE
@subsection @code{TRUNCATE}-Syntax

@findex TRUNCATE

@example
TRUNCATE TABLE tabelle
@end example

In Version 3.23 wird @code{TRUNCATE TABLE} auf @code{COMMIT ; DELETE FROM
tabelle} gemappt. @xref{DELETE}.

Die Unterschiede zwischen @code{TRUNCATE TABLE} und @code{DELETE FROM ..}
sind:

@itemize @bullet
@item
TRUNCATE führt ein Löschen und Neuerzeugen der Tabelle durch, was viel
schneller sit, als Zeilen eine nach der anderen zu löschen.
@item
Nicht transaktionssicher. Sie erhalten einen Fehler, wenn Sie eine aktive
Transaktion haben oder eine aktive Tabellensperre.
@item
Gibt die Anzahl gelöschter Zeilen nicht zurück.
@item
Solange die Tabellendefinitionsdatei @file{tabelle.frm} gültig ist, kann
die Tabelle auf diese Weise neu erzeugt werden, selbst wenn die Daten- oder
Index-Dateien beschädigt wurden.
@end itemize

@code{TRUNCATE} ist eine Oracle-SQL-Erweiterung.

@node REPLACE, LOAD DATA, TRUNCATE, Data Manipulation
@c German node REPLACE
@subsection @code{REPLACE}-Syntax

@findex REPLACE

@example
    REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tabelle [(spalten_name,...)]
        VALUES (ausdruck,...),(...),...
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tabelle [(spalten_name,...)]
        SELECT ...
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tabelle
        SET spalten_name=ausdruck, spalten_name=ausdruck,...
@end example

@code{REPLACE} funktioniert genau wie @code{INSERT}, ausser dass der alte
Datensatz gelöscht wird, bevor ein neuer eingefügt wird, wenn ein alter
Datensatz in der Tabelle denselben Wert wie der neue auf einem eindeutigen
Index hat. @xref{INSERT, , @code{INSERT}}.

Mit anderen Worten können Sie auf die Werte einer alten Zeile nicht mit
einem @code{REPLACE}-Statement zugreifen. In einigen alten MySQL-Versionen
sah es so aus, als könnten Sie das tun, aber das war ein Bug und wurde
korrigiert.

Wenn man einen @code{REPLACE}-Befehl benutzt, gibt
@code{mysql_affected_rows()} 2 zurück, wenn die neue Zeile eine alte
ersetzte. Das liegt daran, dass in diesem Fall eine Zeile eingefügt wurde
und dann das Duplikat gelöscht wurde.

Das macht es einfach zu überprüfen, ob @code{REPLACE} eine Zeile
hinzugefügt oder eine ersetzt hat.


@node LOAD DATA,  , REPLACE, Data Manipulation
@c German node LOAD DATA
@subsection @code{LOAD DATA INFILE}-Syntax

@findex LOAD DATA INFILE

@example
LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'datei.txt'
    [REPLACE | IGNORE]
    INTO TABLE tabelle
    [FIELDS
        [TERMINATED BY '\t']
        [[OPTIONALLY] ENCLOSED BY '']
        [ESCAPED BY '\\' ]
    ]
    [LINES TERMINATED BY '\n']
    [IGNORE Anzahl LINES]
    [(spalten_name,...)]
@end example

Das @code{LOAD DATA INFILE}-Statement liest Zeilen aus einer Textdatei in
eine Tabelle mit sehr hoher Geschwindigkeit. Wenn das
@code{LOCAL}-Schlüsselwort angegeben wird, wird die Datei vom Client-Host
gelesen. Wenn @code{LOCAL} nicht angegeben wird, muss die Datei auf dem
Server liegen. (@code{LOCAL} ist verfügbar ab MySQL-Version 3.22.6.)

Aus Sicherheitsgründen müssen Dateien, die als auf dem Server liegende
Textdateien eingelesen werden, entweder im Datenbank-Verzeichnis liegen
oder von allen lesbar sein. Darüber hinaus brauchen Sie, wenn Sie
@code{LOAD DATA INFILE} mit Server-Dateien benutzen, die
@strong{file}-Berechtigung auf dem Server-Host. @xref{Privileges}.

Wenn Sie das Schlüsselwort @code{LOW_PRIORITY} angeben, wird das
@code{LOAD DATA}-Statement verzögert, bis keine anderen Clients mehr aus
der Tabelle lesen.

Wenn Sie das Schlüsselwort @code{CONCURRENT} bei einer
@code{MyISAM}-Tabelle angeben, können andere Threads Daten aus der Tabelle
abrufen, während @code{LOAD DATA} ausgeführt wird. Die Benutzung dieser
Option beeinflusst natürlich die Performance von @code{LOAD DATA} ein
bisschen, selbst wenn kein anderer Thread die Tabelle zur gleichen Zeit
benutzt.

@code{LOCAL} ist etwas langsamer, als wenn der Server direkt auf die
Dateien zugreifen kann, weil die Inhalte der Datei vom Client-Host auf den
Server-Host übertragen werden müssen. Auf der anderen Seite benötigen Sie
keine @strong{file}-Berechtigung, um lokale Dateien zu laden.

@c old version
Wenn Sie MySQL vor Version 3.23.24 benutzen, können Sie nicht aus einer
FIFO lesen, wenn Sie @code{LOAD DATA INFILE} benutzen. Wenn Sie aus einer
FIFO lesen müssen (zum Beispiel aus der Ausgabe von gunzip), benutzen Sie
statt dessen @code{LOAD DATA LOCAL INFILE}.

@cindex @code{mysqlimport}
Sie können Daten-Dateien auch mit dem @code{mysqlimport}-Dienstprogramm
laden; es arbeitet, indem es einen @code{LOAD DATA INFILE}-Befehl an den
Server schickt. Die @code{--local}-Option veranlasst @code{mysqlimport},
Daten-Dateien vom Client-Host zu lesen. Sie können die
@code{--compress}-Option angeben, um bessere Performance über langsame
Netzwerke zu erzielen, wenn der Client und der Server das komprimierte
Protokoll unterstützen.

Bei der Suche nach Dateien auf dem Server-Host geht der Server nach
folgenden Regeln vor:

@itemize @bullet
@item
Wenn ein absoluter Pfadname angegeben wird, benutzt der Server den
Pfadnamen so, wie er ist.

@item
Wenn ein relativer Pfadname mit einer oder mehreren führenden Bestandteilen
angegeben wird, sucht der Server die Datei relativ zum Daten-Verzeichnis
des Servers.

@item
Wenn ein Dateiname ohne führende Bestandteile angegeben wird, sucht der
Server die Datei im Datenbank-Verzeichnis der aktuellen Datenbank.
@end itemize

Beachten Sie, dass diese Regeln bedeuten, dass eine Datei, die als
@file{./meinedatei.txt} angegeben wird, aus dem Daten-Verzeichnis des
Servers gelesen wird, wohingegen eine Datei, die als @file{meinedatei.txt}
angegeben wird, aus dem Datenbank-Verzeichnis der aktuellen Datenbank
gelesen wird. Das folgende @code{LOAD DATA}-Statement beispielsweise liest
die Datei @file{daten.txt} aus dem Datenbank-Verzeichnis von
@code{datenbank1}, weil @code{datenbank1} die aktuelle Datenbank ist,
obwohl das Statement die Datei explizit in eine Tabelle in der
@code{datenbank2}-Datenbank lädt:

@example
mysql> USE datenbank1;
mysql> LOAD DATA INFILE "daten.txt" INTO TABLE datenbank2.meine_tabelle;
@end example

Die @code{REPLACE}- und @code{IGNORE}-Schlüsselwörter steuern die
Handhabung von Eingabe-Datensätzen, die bestehende Datensätze auf
eindeutigen Schlüsselwerten duplizieren. Wenn Sie @code{REPLACE} angeben,
ersetzen neue Zeilen bestehende Zeilen, die denselben eindeutigen
Schlüsselwert besitzen. Wenn Sie @code{IGNORE} angeben, werden
Eingabe-Zeilen, die eine bestehende Zeile auf einem Schlüsselwert
duplizieren, übersprungen. Wenn Sie keine der beiden Optionen angeben,
tritt ein Fehler auf, wenn ein doppelter Schlüsselwert gefunden wird, und
der Rest der Textdatei wird ignoriert.

Wenn Sie Daten aus einer lokalen Datei mit dem @code{LOCAL}-Schlüsselwort
laden, hat der Server keine Möglichkeit, die Übertragung der Datei mitten
in einer Operation zu beenden. Daher ist das vorgabemäßige Verhalten
dasselbe, als wenn @code{IGNORE} angegeben wäre.

Wenn Sie @code{LOAD DATA INFILE} auf einer leeren @code{MyISAM}-Tabelle
benutzen, werden alle nicht eindeutigen Indexe in einem separaten Stapel
erzeugt (wie bei @code{REPAIR}). Das macht @code{LOAD DATA INFILE}
normalerweise viel schneller, wenn Sie viele Indexe haben.

@code{LOAD DATA INFILE} ist das Komplement von @code{SELECT ... INTO OUTFILE}.
@xref{SELECT, , @code{SELECT}}. Um Daten aus einer Datenbank in eine Datei
zu schreiben, benutzen Sie @code{SELECT ... INTO OUTFILE}. Um die Datei
zurück in die Datenbank zu lesen, benutzen Sie @code{LOAD DATA INFILE}. Die
Syntax der @code{FIELDS}- und @code{LINES}-Klauseln ist für beide Befehle
dieselbe. Beide Klauseln sind optional, aber @code{FIELDS} muss
@code{LINES} vorangehen, wenn beide angegeben werden.

Wenn Sie eine @code{FIELDS}-Klausel angeben, ist jede ihrer Unterklauseln 
(@code{TERMINATED BY}, @code{[OPTIONALLY] ENCLOSED BY} und @code{ESCAPED
BY}) ebenfalls optional, ausser dass Sie zumindest eine von ihnen angeben
müssen.

Wenn Sie keine @code{FIELDS}-Klausel benutzen, sind die Vorgabewerte
dieselben, als wenn Sie folgendes geschrieben hätten:

@example
FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
@end example

Wenn Sie keine @code{LINES}-Klausel angeben, sind die Vorgabewerte
dieselben, als wenn Sie folgendes geschrieben hätten:

@example
LINES TERMINATED BY '\n'
@end example

Mit anderen Worten veranlassen die Vorgabewerte @code{LOAD DATA INFILE},
beim Lesen von Eingaben wie folgt zu arbeiten:

@itemize @bullet
@item
Zeilenbegrenzungen werden an Neue-Zeile-Zeichen gesucht (\n).

@item
Zeilen werden an Tabulatoren (\t) in Felder aufgeteilt.

@item
Es wird nicht davon ausgegangen, dass Felder in Anführungszeichen
eingeschlossen sind.

@item
Tabulatoren, Neue-Zeile-Zeichen oder @samp{\}, denen ein @samp{\}-Zeichen
voran gestellt ist, werden als Literale interpretiert, die Teil des
Feldwerts sind.
@end itemize

Im Vergleich dazu veranlassen die Vorgabewerte von @code{SELECT ... INTO
OUTFILE} dieses, wie folgt zu arbeiten:

@itemize @bullet
@item
Zwischen Felder werden Tabulatoren (\t) geschrieben.

@item
Felder werden nicht in Anführungsstriche geschrieben.

@item
@samp{\} wird benutzt, um Tabulator, Neue-Zeile-Zeichen oder @samp{\}
innerhalb von Feldwerten zu escapen.

@item
Am Ende von Zeilen werden Neue-Zeile-Zeichen (\n) geschrieben.
@end itemize

Beachten Sie, dass Sie @code{FIELDS ESCAPED BY '\\'} (mit zwei Backslashes)
schreiben müssen, damit der Wert als ein einzelner Backslash gelesen wird.

Die @code{IGNORE anzahl LINES}-Option kann benutzt werden, um eine
Kopfzeile aus Spaltennamen am Anfang der Datei zu ignorieren:

@example
mysql> LOAD DATA INFILE "/tmp/datei.txt" into Tabelle test IGNORE 1 LINES;
@end example

Wenn Sie @code{SELECT ... INTO OUTFILE} zusammen mit @code{LOAD DATA
INFILE} benutzen, um Daten aus einer Datenbank in eine Datei zu schreiben
und dann die Datei später zurück in die Datenbank zu lesen, müssen die
Optionen für die Behandlung von Feldern und Zeilen für beide Befehle
übereinstimmen. Ansonsten interpretiert @code{LOAD DATA INFILE} die Inhalte
der Datei nicht korrekt. Angenommen, Sie benutzen @code{SELECT ... INTO
OUTFILE}, um eine Datei zu schreiben, deren Feldern durch Kommas begrenzt
sind:

@example
mysql> SELECT * INTO OUTFILE 'daten.txt'
           FIELDS TERMINATED BY ','
           FROM ...;
@end example

Um die Komma-begrenzte Datei wieder einzulesen, lautet das korrekte
Statement:

@example
mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle2
           FIELDS TERMINATED BY ',';
@end example

Wenn Sie statt dessen versuchen, die Datei mit dem unten stehenden
Statement einzulesen, funktioniert das nicht, weil es @code{LOAD DATA
INFILE} anweist, nach Tabulatoren zwischen Feldern zu suchen:

@example
mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle2
           FIELDS TERMINATED BY '\t';
@end example

Das wahrscheinliche Ergebnis ist, dass jede Eingabezeile als ein einzelnes
Feld interpretiert wird.

@code{LOAD DATA INFILE} kann auch benutzt werden, um Dateien aus externen
Quellen einzulesen. Eine Datei im dBASE-Format zum Beispiel hat Felder, die
durch Kommas getrennt und in Anführungszeichens eingeschlossen sind. Wenn
Zeilen in der Datei von Neue-Zeile-Zeichen begrenzt sind, zeigt der unten
stehende Befehl die Feld- und Zeilen-Handhabungsoptionen, die für das Laden
der Datei benutzt werden:

@example
mysql> LOAD DATA INFILE 'daten.txt' INTO TABLE tabelle
           FIELDS TERMINATED BY ',' ENCLOSED BY '"'
           LINES TERMINATED BY '\n';
@end example

Jede der Feld- oder Zeilen-Handhabungsoptionen kann eine leere Zeichenkette
angeben (@code{''}). Wenn nicht leer, müssen die @code{FIELDS [OPTIONALLY]
ENCLOSED BY}- und @code{FIELDS ESCAPED BY}-Werte ein einzelnes Zeichen
sein. Die @code{FIELDS TERMINATED BY}- und @code{LINES TERMINATED BY}-Werte
können aus mehr als einem Zeichen bestehen. Um zum Beispiel Zeilen zu
schreiben, die durch Wagenrücklauf-Neue-Zeile-Paare getrennt sind, oder um
eine Datei einzulesen, die solche Zeilen enthält, geben Sie eine
@code{LINES TERMINATED BY '\r\n'}-Klausel an.

Um beispielsweise eine Datei mit Witzen einzulesen, die durch @code{%%}
getrennt sind, können Sie folgendes eingeben:

@example
create table witze (a int not null auto_increment primary key, witz text not null);
load data infile "/tmp/witze.txt" into table witze fields terminated by "" lines terminated by "\n%%\n" (witz);
@end example

@code{FIELDS [OPTIONALLY] ENCLOSED BY} steuert die Art von
Anführungszeichen von Feldern. Wenn Sie bei der Ausgabe (@code{SELECT ...
INTO OUTFILE}) das Wort @code{OPTIONALLY} auslassen, sind alle Felder vom
@code{ENCLOSED BY}-Zeichen eingeschlossen. Ein Beispiel einer solchen
Ausgabe (mit Kommas als Feldbegrenzern) ist unten dargestellt:

@example
"1","eine Zeichenkette","100.20"
"2","eine Zeichenkette, die ein Komma (,) enthält","102.20"
"3","eine Zeichenkette, die ein \" Anführungszeichen enthält","102.20"
"4","eine Zeichenkette, die ein \", Anführungszeichen und Komma (,) enthält","102.20"
@end example

Wenn Sie @code{OPTIONALLY} angeben, wird das @code{ENCLOSED BY}-Zeichen nur
benutzt, um @code{CHAR}- und @code{VARCHAR}-Felder zu umschließen:

@example
1,"eine Zeichenkette",100.20
2,"eine Zeichenkette mit einem , Komma",102.20
3,"eine Zeichenkette mit einem \" Anführungszeichen",102.20
4,"eine Zeichenkette mit \", Anführungszeichen und Komma",102.20
@end example

Beachten Sie, dass @code{ENCLOSED BY}-Zeichen innerhalb eines Feldwerts
escapet werden, indem ihnen das @code{ESCAPED BY}-Zeichen vorangestellt
wird. Beachten Sie auch, dass es bei der Angabe eines leeren empty
@code{ESCAPED BY}-Werts möglich ist, Ausgaben zu erzeugen, die nicht
korrekt von @code{LOAD DATA INFILE} eingelesen werden können. Die oben
dargestellte Ausgabe zum Beispiel würde wie im Folgenden gezeigt
erscheinen, wenn das Fluchtzeichen (Escape-Zeichen) leer ist. Beachten Sie,
dass das zweite Feld der vierten Zeile nach dem Anführungszeichen ein Komma
enthält, was (irrtümlich) als Feldbegrenzer interpretiert wird:

@example
1,"eine Zeichenkette",100.20
2,"eine Zeichenkette mit einem , Komma",102.20
3,"eine Zeichenkette mit einem " Anführungszeichen",102.20
4,"eine Zeichenkette mit ", Anführungszeichen und Komma",102.20
@end example

Für die Eingabe wird das @code{ENCLOSED BY}-Zeichen - falls vorhanden - vom
Ende von Feldwerten entfernt. (Das gilt, egal ob @code{OPTIONALLY}
angegeben ist oder nicht; @code{OPTIONALLY} hat keine Auswirkung auf die
Interpretation der Eingabe.) @code{ENCLOSED BY}-Zeichen, denen das
@code{ESCAPED BY}-Zeichen vorangestellt ist, werden als Teil des aktuellen
Feldwerts interpretiert. Zusätzlich werden verdoppelte @code{ENCLOSED
BY}-Zeichen innerhalb von Feldern als ein einzelnes @code{ENCLOSED
BY}-Zeichen interpretiert, falls das Feld selbst mit diesem Zeichen
anfängt. Wenn beispielsweise @code{ENCLOSED BY '"'} angegeben wird, werden
Anführungszeichen wie folgt behandelt:

@example
"Der ""BIG"" Boss"  -> Der "BIG" Boss
Der "BIG" Boss      -> Der "BIG" Boss
Der ""BIG"" Boss    -> Der ""BIG"" Boss
@end example

@code{FIELDS ESCAPED BY} steuert, wie Sonderzeichen geschrieben oder
gelesen werden. Wenn das @code{FIELDS ESCAPED BY}-Zeichen nicht leer ist,
wird es benutzt, um es bei der Ausgabe folgenden Zeichen voranzustellen:
@itemize @bullet
@item
Dem @code{FIELDS ESCAPED BY}-Zeichen
@item
Dem @code{FIELDS [OPTIONALLY] ENCLOSED BY}-Zeichen
@item
Dem ersten Zeichen von @code{FIELDS TERMINATED BY}- und @code{LINES
TERMINATED BY}-Werten
@item
ASCII @code{0} (was tatsächlich nach dem Fluchtzeichen (Escape-Zeichen)
als ASCII @code{'0'} geschrieben wird, nicht ein Byte mit Wert 0)
@end itemize

Wenn das @code{FIELDS ESCAPED BY}-Zeichen leer ist, werden keine Zeichen
escapet. Es ist wahrscheinlich keine gute Idee, ein leeres Fluchtzeichen
(Escape-Zeichen) anzugeben, insbesondere, wenn Feldwerte in Ihren Daten
irgend welche der Zeichen enthalten, die gerade aufgelistet wurden.

Für die Eingabe werden, falls das @code{FIELDS ESCAPED BY}-Zeichen nicht
leer ist, Vorkommen dieses Zeichens entfernt, und die folgenden Zeichen
werden buchstäblich als Teil des Feldwerts genommen. Die Ausnahmen sind ein
escapetes @samp{0} oder @samp{N} (beispielsweise @code{\0} oder @code{\N},
wenn das Fluchtzeichen (Escape-Zeichen) @samp{\} ist). Diese Folgen werden
als ASCII-@code{0} interpretiert (ein Byte mit Wert 0) und @code{NULL}.
Siehe unten zu den Regeln der @code{NULL}-Handhabung.

Weitere Informationen über die @samp{\}-Escape-Syntax finden Sie unter
@ref{Literals}.

In bestimmten Fällen beeinflussen sich die Handhabungsoptionen für Felder
und Zeilen gegenseitig:

@itemize @bullet
@item
Wenn @code{LINES TERMINATED BY} eine leere Zeichenkette ist und
@code{FIELDS TERMINATED BY} nicht leer ist, werden Zeile auch durch
@code{FIELDS TERMINATED BY} begrenzt.
@item
Wenn die @code{FIELDS TERMINATED BY}- und @code{FIELDS ENCLOSED BY}-Werte
beide leer sind (@code{''}), wird ein Festzeilen- (nicht begrenztes) Format
benutzt. Beim Festzeilenformat werden keine Begrenzer zwischen Feldern
benutzt. Statt dessen werden Spaltenwerte geschrieben und gelesen, indem
die Anzeigebreite der Spalten benutzt wird. Wenn eine Spalte zum Beispiel
als @code{INT(7)} deklariert ist, werden Werte für die Spalte mit
7-Zeichen-Feldern geschrieben. Bei der Eingabe werden Werte für die Spalte
mit 7-Zeichen-Feldern bezogen. Festzeilenformate beeinflussen auch die
Handhabung von @code{NULL}-Werten (siehe unten). Beachten Sie, dass
Festgrößenformate nicht funktionieren, wenn Sie einen
Multi-Byte-Zeichensatz benutzen.
@end itemize

Die Handhabung von @code{NULL}-Werten variiert in Abhängigkeit von den
@code{FIELDS}- und @code{LINES}-Optionen, die Sie benutzen:

@itemize @bullet
@item
Bei den vorgabemäßigen @code{FIELDS}- und @code{LINES}-Werten wird
@code{NULL} für die Ausgabe als @code{\N} geschrieben und @code{\N} als
@code{NULL} für die Eingabe gelesen (unter der Annahme, dass das
@code{ESCAPED BY}-Zeichen @samp{\} ist).

@item
Wenn @code{FIELDS ENCLOSED BY} nicht leer ist, wird ein Feld, das das
Literalwort @code{NULL} als seinen Wert enthält, als @code{NULL}-Wert
gelesen (das weicht ab vom Wort @code{NULL}, begrenzt durch @code{FIELDS
ENCLOSED BY}-Zeichen, was als die Zeichenkette @code{'NULL'} gelesen wird).

@item
Wenn @code{FIELDS ESCAPED BY} leer ist, wird @code{NULL} als das Wort
@code{NULL} gelesen.

@item
Beim Festzeilenformat (was auftritt, wenn sowohl @code{FIELDS TERMINATED
BY} als auch @code{FIELDS ENCLOSED BY} leer sind), wird @code{NULL} als
leere Zeichenkette geschrieben. Beachten Sie, dass das dazu führt, dass
@code{NULL}-Werte und leere Zeichenketten in der Tabelle nicht mehr
unterscheidbar sind, wenn in die Datei geschrieben wird, weil sie beide als
leere Zeichenketten geschrieben werden. Wenn Sie in der Lage sein müssen,
diese zu unterscheiden, wenn Sie die Datei wieder einlesen, sollten Sie
kein Festzeilenformat benutzen.
@end itemize

Einige Fälle werden von @code{LOAD DATA INFILE} nicht unterstützt:
@itemize @bullet

@item
Festgrößenzeilen (@code{FIELDS TERMINATED BY} und @code{FIELDS ENCLOSED
BY} sind beide leer) und @code{BLOB}- oder @code{TEXT}-Spalten.

@item
Wenn Sie ein Trennzeichen angeben, das dasselbe wie ein anderes ist oder
einem anderen vorangestellt ist. @code{LOAD DATA INFILE} kann in diesem
Fall die Eingabe nicht korrekt interpretieren. Folgende
@code{FIELDS}-Klausel zum Beispiel würde Probleme bereiten:

@example
FIELDS TERMINATED BY '"' ENCLOSED BY '"'
@end example

@item
Wenn @code{FIELDS ESCAPED BY} leer ist, führt ein Feldwert, der ein
Vorkommen von @code{FIELDS ENCLOSED BY} oder @code{LINES TERMINATED BY}
gefolgt vom @code{FIELDS TERMINATED BY}-Wert enthält, dazu, dass @code{LOAD
DATA INFILE} mit dem Einlesen eines Feldes oder einer Zeile zu früh
aufhört. Das passiert, weil @code{LOAD DATA INFILE} nicht korrekt festlegen
kann, wo der Feld- oder Zeilenwert endet.
@end itemize

Das folgende Beispiel lädt alle Spalten der @code{personen}-Tabelle:

@example
mysql> LOAD DATA INFILE 'personen.txt' INTO TABLE personen;
@end example

Es ist keine Felderliste angegeben, daher erwartet @code{LOAD DATA INFILE},
dass die Eingabefelder ein Feld für jede Tabellenspalte enthalten. Die
Vorgabewerte für @code{FIELDS} und @code{LINES}-Werte werden benutzt.

Wenn Sie Daten nur in einige Tabellenspalten einladen wollen, geben Sie
eine Felderliste an:

@example
mysql> LOAD DATA INFILE 'personen.txt'
           INTO TABLE personen (spalte1,spalte2,...);
@end example

Eine Felderliste müssen Sie ausserdem angeben, wenn die Reihenfolge der
Felder in der Eingabedatei von der Reihenfolge der Tabellenspalten
abweicht. Ansonsten kann MySQL nicht feststellen, wie er Eingabefelder
Tabellenspalten zuordnen soll.

Wenn eine Zeile zu wenige Felder hat, werden die Spalten, für die es kein
Eingabefeld gibt, auf ihre Vorgabewerte gesetzt. Die Zuweisung von
Vorgabewerten ist unter @ref{CREATE TABLE, , @code{CREATE TABLE}}
beschrieben.

Ein leerer Feldwert wird anders interpretiert als ein fehlender Feldwert:

@itemize @bullet
@item
Bei Zeichenketten-Typen wird die Spalte auf die leere Zeichenkette gesetzt.

@item
Bei numerischen Typen wird die Spalte auf @code{0} gesetzt.

@item
Bei Datums- und Zeit-Typen wird die Spalte auf den entsprechenden
``0''-Wert für den Typ gesetzt.
@xref{Date and time types}.
@end itemize

Beachten Sie, dass das dieselben Werte sind, die sich ergeben, wenn Sie
einer Zeichenkette explizit eine leere Zeichenkette zuweisen oder solches
für einen DATE- oder TIME-Type in einem @code{INSERT}- oder
@code{UPDATE}-Statement tun.

@code{TIMESTAMP}-Spalten werden nur dann auf das aktuelle Datum und die
aktuelle Zeit gesetzt, wenn es einen @code{NULL}-Wert für die Spalte gibt
oder (nur für die erste @code{TIMESTAMP}-Spalte) die
@code{TIMESTAMP}-Spalte in der Felderliste ausgelassen ist, wenn eine
Felderliste angegeben wird.

Wenn eine Eingabezeile zu viele Felder hat, werden die zusätzlichen Felder
ignoriert und die Anzahl von Warnungen herauf gezählt.

@code{LOAD DATA INFILE} betrachtet alle Eingaben als Zeichenketten, daher
können Sie für @code{ENUM} oder @code{SET}-Spalten keine numerischen Werte
benutzen, wie Sie das bei @code{INSERT}-Statements tun können. Alle
@code{ENUM}- und @code{SET}-Werte müssen als Zeichenketten angegeben
werden!

@findex mysql_info()
Wenn Sie die C-API benutzen, können Sie Informationen über die Anfrage
durch den Aufruf der API-Funktion @code{mysql_info()} erhalten, wenn die
@code{LOAD DATA INFILE}-Anfrage beendet ist. Das Format der
Informationszeichenkette sieht wie folgt aus:

@example
Records: 1  Deleted: 0  Skipped: 0  Warnings: 0
@end example

Warnungen erfolgen unter denselben Umständen, als wenn Werte über das
@code{INSERT}-Statement (@pxref{INSERT, , @code{INSERT}}) eingefügt werden,
ausser dass @code{LOAD DATA INFILE} zusätzlich Warnungen erzeugt, wenn es
zu wenige oder zu viele Felder in der Eingabezeile gibt. Die Warnungen
werden nirgendwo gespeichert; die Anzahl von Warnungen kann daher nur als
Anhaltspunkt dafür benutzt werden, ob alles gut ging. Wenn Sie Warnungen
erhalten und genau wissen wollen, warum Sie diese erhalten, besteht eine
Möglichkeit dafür darin, @code{SELECT ... INTO OUTFILE} in eine andere
Datei zu benutzen und diese mit der Original-Eingabedatei zu vergleichen.

Wenn Sie wollen, dass @code{LOAD DATA} aus einer Pipe liest, können Sie
folgenden Trick benutzen:

@example
mkfifo /mysql/db/x/x
chmod 666 /mysql/db/x/x
cat < /dev/tcp/10.1.1.12/4711 > /nt/mysql/db/x/x
mysql -e "LOAD DATA INFILE 'x' INTO TABLE x" x
@end example

Wenn Sie eine MySQL-Version vor 3.23.25 benutzen, können Sie das nur mit
@code{LOAD DATA LOCAL INFILE} durchführen.

Weitere Informationen über die Effizienz von @code{INSERT} versus
@code{LOAD DATA INFILE} und Möglichkeiten, die Geschwindigkeit zu steigern,
finden Sie unter @code{LOAD DATA INFILE}, @xref{Insert speed}.


@node Data Definition, Basic User Commands, Data Manipulation, Reference
@c German node Datendefinition
@section Datendefinition: @code{CREATE}, @code{DROP}, @code{ALTER}



@menu
* CREATE DATABASE::             
* DROP DATABASE::               
* CREATE TABLE::                
* ALTER TABLE::                 
* RENAME TABLE::                
* DROP TABLE::                  
* CREATE INDEX::                
* DROP INDEX::                  
@end menu

@node CREATE DATABASE, DROP DATABASE, Data Definition, Data Definition
@c German node CREATE DATABASE
@subsection @code{CREATE DATABASE}-Syntax

@findex CREATE DATABASE

@example
CREATE DATABASE [IF NOT EXISTS] datenbank
@end example

@c German FIX unwrapped @ref
@code{CREATE DATABASE} erzeugt eine Datenbank mit dem angegebenen Namen.
Die Regeln für erlaubte Datenbanknamen finden Sie unter @ref{Legal names}.
Ein Fehler tritt auf, wenn die Datenbank bereits existiert und Sie
@code{IF NOT EXISTS} nicht angeben.

Datenbanken sind in MySQL als Verzeichnisse implementiert, die Dateien
enthalten, die den Tabellen in der Datenbank entsprechen. Weil es keine
Tabellen in einer Datenbank gibt, wenn diese erstmalig erzeugt wird,
erzeugt das @code{CREATE DATABASE}-Statement nur ein Verzeichnis unter dem
MySQL-Daten-Verzeichnis.

@cindex @code{mysqladmin}
Sie können auch mit @code{mysqladmin} Datenbanken erzeugen.
@xref{Client-Side Scripts}.


@node DROP DATABASE, CREATE TABLE, CREATE DATABASE, Data Definition
@c German node DROP DATABASE
@subsection @code{DROP DATABASE}-Syntax

@findex DROP DATABASE

@example
DROP DATABASE [IF EXISTS] datenbank
@end example

@code{DROP DATABASE} löscht alle Tabellen in der Datenbank und löscht die
Datenbank. Wenn Sie ein @code{DROP DATABASE} auf eine symbolisch verknüpfte
Datenbank ausführen, werden sowohl der Link als auch die Original-Datenbank
gelöscht. @strong{Seien Sie mit diesem Befehl sehr vorsichtig!}

@code{DROP DATABASE} gibt die Anzahl von Dateien zurück, die aus dem
Datenbank-Verzeichnis entfernt wurden. Normalerweise ist das dreimal die
Anzahl der Tabellen, weil normalerweise jede Tabelle einer
@file{.MYD}-Datei, einer @file{.MYI}-Datei und einer @file{.frm}-Datei
entspricht.

Der @code{DROP DATABASE}-Befehl entfernt aus dem angegebenen
Datenbank-Verzeichnis alle Dateien mit folgenden Erweiterungen:

@multitable @columnfractions .25 .25 .25 .25
@item .BAK @tab .DAT @tab .HSH @tab .ISD
@item .ISM @tab .ISM @tab .MRG @tab .MYD
@item .MYI @tab .db  @tab .frm
@end multitable

Alle Unterverzeichnisse, die aus 2 Ziffern bestehen
(@code{RAID}-Verzeichnisse), werden ebenfalls gelöscht.

Ab MySQL-Version 3.22 können Sie die Schlüsselwörter @code{IF EXISTS}
benutzen, um eine Fehlermeldung zu vermeiden, die erscheint, wenn die
Datenbank nicht existiert.

@cindex @code{mysqladmin}
Sie können Datenbanken auch mit @code{mysqladmin} löschen.
@xref{Client-Side Scripts}.



@node CREATE TABLE, ALTER TABLE, DROP DATABASE, Data Definition
@c German node CREATE TABLE
@subsection @code{CREATE TABLE}-Syntax

@findex CREATE TABLE


@example
CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tabelle [(create_definition,...)]
[tabellen_optionen] [select_statement]

create_definition:
  spalten_name typ [NOT NULL | NULL] [DEFAULT vorgabe_wert] [AUTO_INCREMENT]
            [PRIMARY KEY] [referenz_definition]
  oder    PRIMARY KEY (index_spalten_name,...)
  oder    KEY [index_name] (index_spalten_name,...)
  oder    INDEX [index_name] (index_spalten_name,...)
  oder    UNIQUE [INDEX] [index_name] (index_spalten_name,...)
  oder    FULLTEXT [INDEX] [index_name] (index_spalten_name,...)
  oder    [CONSTRAINT symbol] FOREIGN KEY index_name (index_spalten_name,...)
            [referenz_definition]
  oder    CHECK (ausdruck)

typ:
        TINYINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    SMALLINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    MEDIUMINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    INT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    INTEGER[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    BIGINT[(laenge)] [UNSIGNED] [ZEROFILL]
  oder    REAL[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
  oder    DOUBLE[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
  oder    FLOAT[(laenge,dezimalstellen)] [UNSIGNED] [ZEROFILL]
  oder    DECIMAL(laenge,dezimalstellen) [UNSIGNED] [ZEROFILL]
  oder    NUMERIC(laenge,dezimalstellen) [UNSIGNED] [ZEROFILL]
  oder    CHAR(laenge) [BINARY]
  oder    VARCHAR(laenge) [BINARY]
  oder    DATE
  oder    TIME
  oder    TIMESTAMP
  oder    DATETIME
  oder    TINYBLOB
  oder    BLOB
  oder    MEDIUMBLOB
  oder    LONGBLOB
  oder    TINYTEXT
  oder    TEXT
  oder    MEDIUMTEXT
  oder    LONGTEXT
  oder    ENUM(wert1,wert2,wert3,...)
  oder    SET(wert1,wert2,wert3,...)

index_spalten_name:
        spalten_name [(laenge)]

referenz_definition:
        REFERENCES tabelle [(index_spalten_name,...)]
                   [MATCH FULL | MATCH PARTIAL]
                   [ON DELETE referenz_option]
                   [ON UPDATE referenz_option]

referenz_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

tabellen_optionen:
	TYPE = @{BDB | HEAP | ISAM | InnoDB | MERGE | MRG_MYISAM | MYISAM @}
or	AUTO_INCREMENT = #
or	AVG_ROW_LENGTH = #
or	CHECKSUM = @{0 | 1@}
or	COMMENT = "string"
or	MAX_ROWS = #
or	MIN_ROWS = #
or	PACK_KEYS = @{0 | 1 | DEFAULT@}
or	PASSWORD = "string"
or	DELAY_KEY_WRITE = @{0 | 1@}
or      ROW_FORMAT= @{ default | dynamic | fixed | compressed @}
or	RAID_TYPE= @{1 | STRIPED | RAID0 @} RAID_CHUNKS=#  RAID_CHUNKSIZE=#
or	UNION = (tabelle,[tabelle...])
or	INSERT_METHOD= @{NO | FIRST | LAST @}
or      DATA directory="verzeichnis"
or      INDEX directory="verzeichnis"

select_statement:
	[IGNORE | REPLACE] SELECT ...  (jedes zulässige SELECT-Statement)
@end example

@code{CREATE TABLE} erzeugt eine Tabelle mit dem angegebenen Namen in der
aktuellen Datenbank. Die Regeln für erlaubte Tabellennamen finden Sie unter
@ref{Legal names}. Ein Fehler tritt auf, wenn es keine aktuelle
Datenbank gibt oder wenn die Tabelle bereits existiert.

Ab MySQL-Version 3.22 kann der Tabellenname als @code{datenbank.tabelle}
angegeben werden. Das funktioniert unabhängig davon, ob es eine aktuelle
Datenbank gibt oder nicht.

In MySQL-Version 3.23 können Sie das @code{TEMPORARY}-Schlüsselwort
benutzen, wenn Sie eine Tabelle erzeugen. Eine temporäre Tabelle wird
automatisch gelöscht, wenn eine Verbindung stirbt und der Name sich auf die
Verbindung bezieht. Das bedeutet, dass zwei verschiedene Verbindungen beide
denselben temporären Tabellenname benutzen können, oder miteinander oder
einer bestehenden Tabelle gleichen Namens in Konflikt zu geraten. (Die
bestehende Tabelle ist versteckt, bis die temporäre Tabelle gelöscht wird.)

Ab MySQL-Version 3.23 können Sie die Schlüsselwörter @code{IF NOT EXISTS}
benutzen, so dass kein Fehler auftritt, wenn die Tabelle bereits besteht.
Beachten Sie, dass keine Überprüfung erfolgt, dass die Tabellenstrukturen
identisch sind.

Jede Tabelle @code{tabelle} wird durch einige Dateien im
Datenbank-Verzeichnis dargestellt. Im Falle von MyISAM-Tabellen erhalten
Sie:

@multitable @columnfractions .2 .8
@item @strong{Datei} @tab @strong{Zweck}
@item @code{tabelle.frm} @tab Tabellendefinitionsdatei (form)
@item @code{tabelle.MYD} @tab Daten-Datei
@item @code{tabelle.MYI} @tab Index-Datei
@end multitable

Weitere Information über die Eigenschaften der verschiedenen Spaltentypen
finden Sie unter @ref{Column types}:

@itemize @bullet
@item
Wenn weder @code{NULL} noch @code{NOT NULL} angegeben ist, wird die Spalte
behandelt, als wenn @code{NULL} angegeben worden wäre.

@item
Eine Ganzzahl-Spalte kann das zusätzliche Attribut @code{AUTO_INCREMENT}
haben. Wenn Sie einen Wert von @code{NULL} (empfohlen) oder @code{0} in
eine @code{AUTO_INCREMENT}-Spalte einfügen, wird die Spalte auf
@code{wert+1} gesetzt, wobei @code{wert} der größte momentan in der
Tabelle vorhandene Spaltenwert ist. @code{AUTO_INCREMENT}-Folgen fangen mit
@code{1} an. @xref{mysql_insert_id, , @code{mysql_insert_id()}}.

Wenn Sie eine Zeile löschen, die den höchsten Wert einer
@code{AUTO_INCREMENT}-Spalte enthält, wird der Wert bei einer @code{ISAM}-
oder @code{BDB}-Tabelle wieder verwendet, nicht aber bei einer
@code{MyISAM}- oder @code{InnoDB}-Tabelle. Wenn Sie alle Zeilen in der
Tabelle mit @code{DELETE FROM tabelle} (ohne ein @code{WHERE}) im
@code{AUTOCOMMIT}-Modus löschen, fängt die Folge bei allen Tabellentypen
von Neuem an.

@strong{HINWEIS:} Es darf nur eine @code{AUTO_INCREMENT}-Spalte pro Tabelle
geben und diese muss indiziert sein. MySQL-Version 3.23 funktioniert
darüber hinaus nur korrekt, wenn die @code{AUTO_INCREMENT}-Spalte nur
positive Werte hat. Das Einfügen einer negativen Zahl wird als Einfügen
einer sehr großen positiven Zahl betrachtet. Damit werden
Genauigkeitsprobleme vermieden, wenn Zahlen vom positiven zum negativen
Bereich übergehen. Ausserdem wird sichergestellt, dass man nicht
versehentlich eine @code{AUTO_INCREMENT}-Spalte erhält, die 0 enthält.

@cindex ODBC-Kompatibilität
@cindex Kompatibilität, mit ODBC
Um MySQL kompatibel mit einigen ODBC-Applikationen zu machen, können Sie
die letzte eingefügte Zeile mit folgender Anfrage finden:

@example
SELECT * FROM tabelle WHERE auto_spalte IS NULL
@end example

@item
@code{NULL}-Werte werden bei @code{TIMESTAMP}-Spalten anders als bei
anderen Spaltentypen gehandhabt. Sie können @code{NULL} nicht wortgetreu in
einer @code{TIMESTAMP}-Spalte speichern: Wenn Sie die Spalte auf
@code{NULL} setzen, wird sie auf das aktuelle Datum und die aktuelle Zeit
gesetzt. Weil @code{TIMESTAMP}-Spalten sich auf diese Art verhalten,
treffen die @code{NULL}- und @code{NOT NULL}-Attribute nicht auf normale
Art zu und werden ignoriert, wenn Sie sie angeben.

Auf der anderen Seite berichtet der Server, um es für MySQL-Clients
leichter zu machen, @code{TIMESTAMP}-Spalten zu benutzen, dass solchen
Spalten @code{NULL}-Werte zugewiesen werden können (was stimmt), obwohl
@code{TIMESTAMP} nie wirklich einen @code{NULL}-Wert enthalten wird. Sie
können das sehen, wenn Sie @code{DESCRIBE tabelle} eingeben, um eine
Beschreibung Ihrer Tabelle zu erhalten.

Beachten Sie, dass das Setzen einer @code{TIMESTAMP}-Spalte auf @code{0}
nicht dasselbe ist wie das Setzen auf @code{NULL}, weil @code{0} ein
gültiger @code{TIMESTAMP}-Wert ist.

@item
Wenn kein @code{DEFAULT}-Wert für eine Spalte angegeben wird, weist MySQL
automatisch einen zu.

Wenn die Spalte @code{NULL} als Wert aufnehmen darf, ist der Vorgabewert
@code{NULL}.

Wenn die Spalte als @code{NOT NULL} deklariert ist, hängt der Vorgabewert
vom Spaltentyp ab:

@itemize @minus
@item
Bei numerischen Typen ausser denen, die mit dem
@code{AUTO_INCREMENT}-Attribut deklariert wurden, ist der Vorgabewert
@code{0}. Bei einer @code{AUTO_INCREMENT}-Spalte ist der Vorgabewert der
nächste Wert in der Folge.

@item
Bei Datums- und Zeit-Typen ausser @code{TIMESTAMP} ist der Vorgabewert der
entsprechende 0-Wert für den Typ. Bei der ersten @code{TIMESTAMP}-Spalte
einer Tabelle ist der Vorgabewert das aktuelle Datum und die aktuelle Zeit.
@xref{Date and time types}.

@item
Bei Zeichenketten-Typen ausser @code{ENUM} ist der Vorgabewert die leere
Zeichenkette. Bei @code{ENUM} ist der Vorgabewert der erste
Aufzählungswert.
@end itemize

Vorgabewerte müssen Konstanten sein. Das heißt zum Beispiel, dass Sie den
Vorgabewert einer DATE-Spalte nicht als Wert einer Funktion wie
@code{NOW()} oder @code{CURRENT_DATE} setzen können.

@item
@code{KEY} ist ein Synonym für @code{INDEX}.

@item
In MySQL darf ein @code{UNIQUE}-Schlüssel nur unterschiedliche Werte haben.
Ein Fehler tritt auf, wenn Sie versuchen, eine neue Zeile hinzuzufügen, der
Schlüsselwert dem einer bestehenden Zeile entspricht.

@item
@tindex PRIMARY KEY
Ein @code{PRIMARY KEY} ist ein eindeutiger @code{KEY} mit der zusätzlichen
Beschränkung, dass alle Schlüsselspalten als @code{NOT NULL} deklariert
sein müssen. In MySQL wird der Schlüssel @code{PRIMARY} genannt. Eine
Tabelle darf nur einen @code{PRIMARY KEY} haben. Wenn Sie keinen
@code{PRIMARY KEY} haben und irgend welche Applikationen nach einem
@code{PRIMARY KEY} in Ihrer Tabelle verlangen, gibt MySQL den ersten
@code{UNIQUE}-Schlüssel, der keinerlei @code{NULL}-Spalten hat, als
@code{PRIMARY KEY} zurück.

@item
Ein @code{PRIMARY KEY} kann ein mehrspaltiger Index sein. Sie können jedoch
keinen mehrspaltiger Index mit dem @code{PRIMARY KEY}-Schlüsselattribut in
einer Spaltenspezifikation erzeugen. Wenn Sie das tun, wird nur die erste
Spalte als @code{PRIMARY} gekennzeichnet. Sie müssen die @code{PRIMARY
KEY(index_spalten_name, ...)}-Syntax benutzen.

@item
Wenn der @code{PRIMARY}- oder @code{UNIQUE}-Schlüssel aus nur einer Spalte
besteht und diese vom Typ Ganzzahl ist, können Sie auf sie auch als
@code{_rowid} verweisen (neu ab Version 3.23.11).

@item
Wenn Sie einem Index keinen Namen zuweisen, wird dem Index derselbe Name
zugewiesen wie der erste @code{index_spalten_name}, mit einem optionalen
Suffix (@code{_2}, @code{_3}, @code{...}), um ihn eindeutig zu machen. Sie
können die Indexnamen für eine Tabelle mit @code{SHOW INDEX FROM tabelle}
anzeigen. @xref{SHOW, , @code{SHOW}}.

@item
@cindex @code{NULL}-Werte und Indexe
@cindex Indexe und @code{NULL}-Werte
Nur der @code{MyISAM}-Tabellentyp unterstützt Indexe auf Spalten, die
@code{NULL}-Werte enthalten können. In anderen Fällen müssen Sie solche
Spalten als @code{NOT NULL} deklarieren, sonst tritt ein Fehler auf.

@item
Mit der @code{spalten_name(laenge)}-Syntax können Sie einen Index
festlegen, der nur einen Teil einer @code{CHAR}- oder @code{VARCHAR}-Spalte
enthält. Das kann die Index-Datei viel kleiner machen.
@xref{Indexes}.

@item
@cindex @code{BLOB}-Spalten, Indexierung
@cindex Indexe und @code{BLOB}-Spalten
@cindex @code{TEXT}-Spalten, Indexierung
@cindex Indexe und @code{TEXT}-Spalten
Nur der @code{MyISAM}-Tabellentyp unterstützt Indexierung auf @code{BLOB}-
und @code{TEXT}-Spalten. Wenn Sie einen Index auf eine @code{BLOB}- oder
@code{TEXT}-Spalte setzen, MÜSSEN Sie immer die Länge des Indexes angeben:
@example
CREATE TABLE test (blob_spalte BLOB, index(blob_spalte(10)));
@end example

@item
Wenn Sie @code{ORDER BY} oder @code{GROUP BY} bei einer @code{TEXT}- oder
@code{BLOB}-Spalte benutzen, werden nur die ersten @code{max_sort_length}
Bytes benutzt. @xref{BLOB,  , @code{BLOB}}.

@item
Ab MySQL-Version 3.23.23 können Sie auch spezielle @strong{FULLTEXT}-Indexe
erzeugen, Diese werden für Volltextsuche benutzt. Nur der
@code{MyISAM}-Tabellentyp unterstützt @code{FULLTEXT}-Indexe. Sie können
auf @code{VARCHAR}- und @code{TEXT}-Spalten erzeugt werden. Die Indexierung
erfolgt immer über die gesamte Spalte, teilweise Indexierung wird nicht
unterstützt. Siehe @ref{Fulltext Search} für Details zur Funktionsweise.

@item
Die @code{FOREIGN KEY}-, @code{CHECK}- und @code{REFERENCES}-Klauseln tun
momentan noch nichts. Die Syntax wird nur aus Gründen der Kompatibilität
bereit gestellt, um das Portieren von Code von anderen SQL-Servern zu
erleichtern und um Applikationen laufen zu lassen, die Tabellen mit
Referenzen erzeugen.
@c German FIX old ref was @xref{Fehlende Funktionen}.
@xref{ANSI diff Foreign Keys}.

@item
Jede @code{NULL}-Spalte benötigt ein zusätzliches Bit, gerundet auf das
nächste Byte.

@item
Die maximale Datensatzlänge in Bytes kann wie folgt berechnet werden:

@example
Zeilenlänge = 1
              + (Summe Spaltenlängen)
              + (Anzahl von NULL-Spalten + 7)/8
              + (Anzahl von Spalten variabler Länge)
@end example

@item
Die @code{tabellen_optionen}- und @code{SELECT}-Optionen sind implementiert
ab MySQL-Version 3.23.

Die unterschiedlichen Tabellentypen sind:

@multitable @columnfractions .20 .80
@item BDB oder Berkeley_db @tab Transaktionssichere Tabellen mit Seitensperren (Page Locking). @xref{BDB}.
@item HEAP @tab Die Daten dieser Tabelle werden nur im Arbeitsspeicher gehalten. @xref{HEAP}.
@item ISAM @tab Der Original-Tabellen-Handler. @xref{ISAM}.
@item InnoDB @tab Transaktionssichere Tabellen mit Zeilensperren. @xref{InnoDB}.
@item MERGE @tab Eine Sammlung von MyISAM-Tabellen, die als eine Tabelle benutzt werden. @xref{MERGE}.
@item MRG_MERGE @tab Ein Alias für MERGE-Tabellen.
@item MyISAM @tab Der neue binäre portable Tabellen-Handler, der ISAM ersetzt. @xref{MyISAM}.
@end multitable
@xref{Table types}.

Wenn ein Tabellentyp angegeben wird und dieser besondere Typ nicht
verfügbar ist, wählt MySQL den Tabellentyp, der dem angegebenen am nächsten
kommt. Wenn beispielsweise @code{TYPE=BDB} angegeben wird und die
Distribution von MySQL keine @code{BDB}-Tabellen unterstützt, wird die
Tabelle statt dessen als @code{MyISAM} erzeugt.

Die anderen Tabellenoptionen werden benutzt, um das Verhalten der Tabelle
zu optimieren. In den meisten Fällen müssen Sie keine davon angeben. Die
Optionen funktionieren bei allen Tabellentypen, falls nicht anders
angegeben:

@multitable @columnfractions .20 .80
@item @code{AUTO_INCREMENT} @tab Der nächste auto_increment-Wert, den Sie für Ihre Tabelle setzen wollen (MyISAM).
@item @code{AVG_ROW_LENGTH} @tab Näherungsweise die durchschnittliche Zeilenlänge Ihrer Tabelle. Diese Option müssen Sie nur für große Tabellen mit unterschiedlich großen Datensätzen setzen.
@item @code{CHECKSUM} @tab Setzen Sie diesen Wert auf 1, wenn Sie wollen, dass MySQL eine Prüfsumme für alle Zeilen unterhält (macht die Tabelle ein bisschen langsamer bei der Aktualisierung, aber macht es einfacher, beschädigte Tabellen zu finden) (MyISAM).
@item @code{COMMENT} @tab Ein 60-Zeichen-Kommentar für Ihre Tabelle.
@item @code{MAX_ROWS} @tab Maximale Anzahl von Zeilen, die Sie in Ihrer Tabelle zu speichern planen.
@item @code{MIN_ROWS} @tab Minimale Anzahl von Zeilen, die Sie in Ihrer Tabelle zu speichern planen.
@item @code{PACK_KEYS} @tab Setzen Sie diesen Wert auf 1, wenn Sie einen kleineren Index erhalten wollen. Das macht Aktualisierungen üblicherweise langsamer und liest schneller (MyISAM, ISAM). Setzen auf 0 schaltet die Komprimierung von Schlüsseln ab. Setzen auf @code{DEFAULT} (MySQL 4.0) weist die Tabellen-Handler an, nur lange @code{CHAR}- / @code{VARCHAR}-Spalten zu packen.
@item @code{PASSWORD} @tab Verschlüsselt die @code{.frm}-Datei mit einem Passwort. Diese Option tut nichts in der Standard-MySQL-Version.
@item @code{DELAY_KEY_WRITE} @tab Setzen Sie diesen Wert auf 1, wenn Sie Schlüssel-Tabellen-Aktualisierungen verzögern wollen, bis die Tabelle geschlossen wird (MyISAM).
@item @code{ROW_FORMAT} @tab Definiert, wie die Zeilen gespeichert werden sollen. Momentan funktioniert diese Option nur bei MyISAM-Tabellen, die die @code{DYNAMIC}- und @code{FIXED}-Zeilenformate unterstützen. @xref{MyISAM table formats}.
@end multitable

Wenn Sie eine @code{MyISAM}-Tabelle benutzen, verwendet MySQL das Produkt
aus @code{max_rows * avg_row_length} um zu entscheiden, wie Groß die
resultierende Tabelle sein wird. Wenn Sie keine der obigen Optionen
angeben, ist die maximale Größe für eine Tabelle 4 GB (oder 2 GB, wenn Ihr
Betriebssystem nur 2 GB-Tabellen unterstützt). Das geschieht, um
Zeigergrößen gering zu halten und um den Index kleiner und schneller zu
machen, wenn Sie nicht wirklich große Dateien benötigen.

Wenn Sie @code{PACK_KEYS} nicht benutzen, ist die Vorgabe, nur
Zeichenketten zu komprimieren, nicht Zahlen. Wenn Sie @code{PACK_KEYS=1}
benutzen, werden auch Zahlen komprimiert.

Wenn Sie binäre Zahlschlüssel komprimieren, benutzt MySQL die
Präfix-Komprimierung. Das bedeutet, dass Sie nur dann einen Nutzen daraus
ziehen, wenn Sie Zahlen haben, die sich oft wiederholen. Präfix-Kompression
bedeutet, das jeder Schlüssel ein zusätzliches Byte benötigt, um
darzustellen, wie viele Bytes des vorherigen Schlüssels für den nächsten
Schlüssel dieselben sind (beachten Sie, dass der Zeiger auf die Zeile in
der Reihenfolge 'hohes Byte zuerst' direkt nach dem Schlüssel gespeichert
wird, um die Kompression zu verbessern). Das heißt, wenn Sie viele gleiche
Schlüssel auf zwei Zeilen hintereinander haben, werden alle folgenden
'gleichen' Schlüssel üblicherweise nur 2 Bytes in Anspruch nehmen
(inklusive dem Zeiger auf die Zeile). Vergleichen Sie das mit dem
Normalfall, bei dem die folgenden Schlüssel speicher_platz_fuer_schlüssel +
zeiger_groesse beanspruchen (üblicherweise 4). Auf der anderen Seite
verlieren Sie 1 Byte pro Schlüssel, wenn alle Schlüssel völlig
unterschiedlich sind, falls der Schlüssel kein Schlüssel ist, der
@code{NULL}-Werte haben kann (in diesem Fall wird die komprimierte
Schlüssellänge, die im selben Byte gespeichert ist, benutzt, um zu
kennzeichnen, ob ein Schlüssel @code{NULL} ist).

@item
Wenn Sie ein @code{SELECT} nach dem @code{CREATE}-Statement angeben,
erzeugt MySQL neue Felder für alle Elemente im @code{SELECT}. Beispiel:

@example
mysql> CREATE TABLE test (a int not null auto_increment,
           primary key (a), key(b))
           TYPE=MyISAM SELECT b,c from test2;
@end example

Das erzeugt eine @code{MyISAM}-Tabelle mit drei Spalten a, b und c.
Beachten Sie, dass die Spalten des @code{SELECT}-Statements an die rechte
Seite der Tabelle angehängt werden, nicht überlappend. Nehmen wir folgendes
Beispiel:

@example
mysql> select * from foo;
+---+
| n |
+---+
| 1 |
+---+           

mysql> create table bar (m int) select n from foo;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0
 
mysql> select * from bar;
+------+---+
| m    | n |
+------+---+
| NULL | 1 |
+------+---+
1 row in set (0.00 sec)                           
@end example

Für jede Zeile in Tabelle @code{foo} wird eine Zeile in @code{bar} mit den
Werten von @code{foo} und Vorgabewerten für die neuen Spalten eingefügt.

@code{CREATE TABLE ... SELECT} erzeugt nicht automatisch irgend welche
Indexe. Das wird absichtlich gemacht, um den Befehl so flexibel wie möglich
zu machen. Wenn Sie Indexe in der erzeugten Tabelle haben wollen, geben Sie
diese vor dem @code{SELECT}-Statement an:

@example
mysql> create table bar (unique (n)) select n von foo;
@end example

Wenn Fehler beim Kopieren der Daten in die Tabelle auftreten, wird diese
automatisch gelöscht.

Um sicherzustellen, dass die Update-Log-Datei/Binär-Log-Datei benutzt
werden kann, um die Original-Tabellen neu zu erzeugen, läßt MySQL keine
gleichzeitigen Einfügeoperationen während @code{CREATE TABLE .... SELECT}
zu.
@item
Die @code{RAID_TYPE}-Option hilft, die 2 GB- / 4 GB-Grenze für die
MyISAM-Daten-Datei zu durchbrechen (nicht für die Index-Datei), auf
Betriebssystemen, die keine großen Dateien unterstützen.
Sie erzielen mehr Geschwindigkeit vom I/O-Flaschenhals, wenn Sie die
@code{RAID}-Verzeichnisse auf unterschiedliche physikalische Platten legen.
@code{RAID_TYPE} funktioniert auf jedem Betriebssystem, solange Sie MySQL
mit @code{--with-raid} konfiguriert haben. Momentan ist der einzige
zulässige @code{RAID_TYPE} @code{STRIPED} (@code{1} und @code{RAID0} sind
Aliase dafür).

Wenn Sie @code{RAID_TYPE=STRIPED} bei einer @code{MyISAM}-Tabelle angeben,
erzeugt @code{MyISAM} @code{RAID_CHUNKS}-Unterverzeichnisse namens 00, 01,
02 im Datenbank-Verzeichnis. In jedem dieser Verzeichnisse erzeugt
@code{MyISAM} eine @code{tabelle.MYD}. Wenn Sie Daten in die Daten-Datei
schreiben, mappt der @code{RAID}-Handler die ersten @code{RAID_CHUNKSIZE} *
1024 Bytes auf die erste Datei, die nächsten @code{RAID_CHUNKSIZE} * 1024
Bytes auf die nächste Datei usw.

@item
@code{UNION} wird benutzt, wenn Sie eine Sammlung identischer Tabelle als
eine benutzen wollen. Das funktioniert nur bei MERGE-Tabellen. @xref{MERGE}.

Momentan benötigen Sie @code{SELECT}-, @code{UPDATE}-
und-@code{DELETE}-Berechtigungen auf die Tabellen, die Sie auf eine
@code{MERGE}-Tabelle mappen. Alle gemappten Tabellen müssen sich in
derselben Datenbank wie die @code{MERGE}-Tabelle befinden.

@item
Wenn Sie Daten in eine @code{MERGE}-Tabelle einfügen wollen, müssen Sie mit
@code{INSERT_METHOD} angeben, in welche Tabelle die Zeile eingefügt werden
soll. @xref{MERGE}.

@item
In der erzeugten Tabelle wird der @code{PRIMARY}-Schlüssel zuerst
platziert, gefolgt von allen @code{UNIQUE}-Schlüsseln und danach von den
normalen Schlüsseln. Das hilft dem MySQL-Optimierer zu priorisieren,
welcher Schlüssel benutzt werden soll, und auch, Duplikate von
@code{UNIQUE}-Schlüsseln zu entdecken.

@item
Wenn Sie @code{DATA directory="verzeichnis"} oder @code{INDEX
directory="verzeichnis"} benutzen, können Sie angeben, wohin die
Tabellen-Handler ihre Tabellen- und Index-Dateien legen sollen. Das
funktioniert nur bei @code{MyISAM}-Tabellen in @code{MySQL} 4.0, wenn Sie
die @code{--skip-symlink}-Option nicht benutzen. @xref{Symbolic links to tables}.

@end itemize


@menu
* Silent column changes::       
@end menu

@node Silent column changes,  , CREATE TABLE, CREATE TABLE
@c German node Stille Spaltentyp-Änderungen
@subsubsection Stille Spaltentyp-Änderungen

@cindex Stille Spaltentyp-Änderungen

In einigen Fällen ändert MySQL lautlos eine Spaltenspezifikation von der,
die in einem @code{CREATE TABLE}-Statement angegeben wurde. (Das kann auch
bei @code{ALTER TABLE} passieren.):

@itemize @bullet
@item
@code{VARCHAR}-Spalten mit einer Länge kleiner 4 werden in @code{CHAR}
geändert.

@item
Wenn irgend eine Spalte in einer Tabelle eine variable Länge hat, hat im
Ergebnis jede Zeile eine variable Länge. Wenn daher eine Tabelle irgend
welche Spalten variabler Länge enthält (@code{VARCHAR}, @code{TEXT} oder
@code{BLOB}), werden alle @code{CHAR}-Spalten, die länger als drei Zeichen
sind, in @code{VARCHAR}-Spalten umgewandelt. Das beeinflusst die Benutzung
dieser Spalten in keiner Weise, denn in MySQL ist @code{VARCHAR} nur eine
andere Art, Zeichen zu speichern. MySQL führt diese Umwandlung durch, weil
sie Platz spart und Tabellenoperationen schneller macht.
@xref{Table types}.

@item
@code{TIMESTAMP}-Anzeigebreiten müssen geradzahlig und im Bereich von 2 bis
14 sein. Wenn Sie eine Anzeigebreite von 0 oder größer als 14 angeben,
wird die Größe auf 14 gesetzt. Ungerade Werte im Bereich von 1 bis 13
werden auf den nächst höheren geraden Wert gesetzt.

@item
Sie können keinen echten @code{NULL}-Wert in einer @code{TIMESTAMP}-Spalte
speichern. Wenn Sie sie auf @code{NULL} setzen, wird sie auf das aktuelle
Datum und die aktuelle Zeit gesetzt. Weil sich @code{TIMESTAMP}-Spalten so
verhalten, treffen die Attribute @code{NULL} und @code{NOT NULL} nicht auf
normale Weise zu und werden ignoriert, wenn Sie sie angeben. @code{DESCRIBE
tabelle} zeigt dagegen immer an, dass einer @code{TIMESTAMP}-Spalte
@code{NULL}-Werte zugewiesen werden können.

@item
MySQL mappt bestimmte Spaltentypen, die von anderen
SQL-Datenbank-Herstellern benutzt werden, auf MySQL-Typen.
@xref{Other-vendor column types}.
@end itemize

Wenn Sie sehen wollen, ob MySQL einen anderen Spaltentyp als den, den Sie
angegeben haben, benutzt hat, geben Sie nach dem Erzeugen oder Ändern Ihrer
Tabelle ein @code{DESCRIBE tabelle}-Statement ein.

@cindex @code{myisampack}
Bestimmte andere Spaltentyp-Änderungen können auftreten, wenn Sie eine
Tabelle mit @code{myisampack} komprimieren. @xref{Compressed format}.


@node ALTER TABLE, RENAME TABLE, CREATE TABLE, Data Definition
@c German node ALTER TABLE
@subsection @code{ALTER TABLE}-Syntax

@findex ALTER TABLE

@example
ALTER [IGNORE] TABLE tabelle aenderungs_angabe [, aenderungs_angabe ...]

aenderungs_angabe:
        ADD [COLUMN] create_definition [FIRST | AFTER spalten_name]
  oder    ADD [COLUMN] (create_definition, create_definition,...)
  oder    ADD INDEX [index_name] (index_spalten_name,...)
  oder    ADD PRIMARY KEY (index_spalten_name,...)
  oder    ADD UNIQUE [index_name] (index_spalten_name,...)
  oder    ADD FULLTEXT [index_name] (index_spalten_name,...)
  or	ADD [CONSTRAINT symbol] FOREIGN KEY index_name (index_spalten_name,...)
            [referenz_definition]
  oder    ALTER [COLUMN] spalten_name @{SET DEFAULT literal | DROP DEFAULT@}
  oder    CHANGE [COLUMN] alter_spalten_name create_definition
  oder    MODIFY [COLUMN] create_definition
  oder    DROP [COLUMN] spalten_name
  oder    DROP PRIMARY KEY
  oder    DROP INDEX index_name
  oder    DISABLE KEYS
  oder    ENABLE KEYS
  oder    RENAME [TO] neue_tabelle
  oder    ORDER BY spalte
  oder    tabellen_optionen
@end example

Mit @code{ALTER TABLE} können Sie die Struktur einer bestehenden Tabelle
ändern. Sie können beispielsweise Spalten hinzufügen oder löschen, Indexe
erzeugen oder löschen, den Typ bestehender Spalten ändern oder Spalten oder
die Tabelle selbst umbenennen. Sie können auch den Kommentar für die
Tabelle und den Typ der Tabelle ändern. @xref{CREATE TABLE, , @code{CREATE TABLE}}.

Wenn Sie @code{ALTER TABLE} benutzen, um eine Spaltenspezifikation zu
ändern, und @code{DESCRIBE tabelle} anzeigt, dass die Spalte nicht geändert
wurde, ist es möglich, dass MySQL Ihre Änderungen aus einem der Gründe
ignoriert hat, die in @ref{Silent column changes} beschrieben sind.
Wenn Sie beispielsweise versuchen, eine @code{VARCHAR}-Spalte zu
@code{CHAR} zu ändern, benutzt MySQL dennoch @code{VARCHAR}, wenn die
Tabelle weitere Spalten variabler Länge enthält.

@code{ALTER TABLE} funktioniert mittels Anlegen einer temporären Kopie der
Original-Tabelle. Die Änderungen werden an der Kopie durchgeführt, dann
wird die Original-Tabelle gelöscht und die neue umbenannt. Das wird so
durchgeführt, dass alle Aktualisierungen automatisch ohne irgend welche
fehlgeschlagenen Aktualisierungen an die neue Tabelle weitergeleitet
werden. Während @code{ALTER TABLE} ausgeführt wird, ist die alte Tabelle
durch andere Clients lesbar. Aktualisierungen und Schreibvorgänge in die
Tabelle werden angehalten, bis die neue Tabelle bereit ist.

Beachten Sie, dass MySQL immer eine temporäre Tabelle anlegt, wenn Sie für
@code{ALTER TABLE} irgend eine Option ausser @code{RENAME} angeben, selbst
wenn die Daten eigentlich nicht kopiert werden müssten (zum Beispiel, wenn
Sie einen Spaltennamen ändern). Wir planen, dass zu beheben, aber da man
@code{ALTER TABLE} normalerweise nicht ausführen muss, ist das auf unserer
TODO-Liste nicht sehr hoch angesetzt.

@itemize @bullet
@item
Um @code{ALTER TABLE} ausführen zu können, benötigen Sie @strong{ALTER}-,
@strong{INSERT}- und @strong{CREATE}-Berechtigungen für die Tabelle.

@item
@code{IGNORE} ist eine MySQL-Erweiterung zu ANSI-SQL92. Es steuert, wie
@code{ALTER TABLE} funktioniert, wenn es in der neuen Tabelle Duplikate auf
eindeutigen Schlüsseln gibt. Wenn @code{IGNORE} nicht angegeben wird, wird
das Kopieren abgebrochen und zurückgesetzt. Wenn @code{IGNORE} angegeben
wird, wird bei Zeilen mit Duplikaten auf einem eindeutigen Schlüssel nur
die erste Zeile benutzt, die anderen werden gelöscht.

@item
Sie können mehrfache @code{ADD}-, @code{ALTER}-, @code{DROP}- und
@code{CHANGE}-Klauseln in einem einzigen @code{ALTER TABLE}-Statement
angeben. Das ist eine MySQL-Erweiterung zu ANSI-SQL92, welches nur eine
Klausel pro @code{ALTER TABLE}-Statement zuläßt.

@item
@code{CHANGE spalten_name}, @code{DROP spalten_name} und @code{DROP INDEX}
sind MySQL-Erweiterungen zu ANSI-SQL92.

@item
@code{MODIFY} ist eine Oracle-Erweiterung zu @code{ALTER TABLE}.

@item
Das optionale Wort @code{COLUMN} kann weggelassen werden.

@item
Wenn Sie @code{ALTER TABLE tabelle RENAME TO neuer_name} ohne weitere
Optionen benutzen, benennt MySQL einfach die Dateien um, die der Tabelle
@code{tabelle} entsprechen. Es besteht keine Notwendigkeit, die temporäre
Tabelle zu erzeugen. @xref{RENAME TABLE,, @code{RENAME TABLE}}.

@item
Ab @strong{MySQL 4.0} kann das obige Feature explizit aktiviert werden.
@code{ALTER TABLE ... DISABLE KEYS} veranlasst MySQL, mit dem Aktualisieren
nicht eindeutiger Indexe für die @code{MyISAM}-Tabelle aufzuhören. Dann
sollte @code{ALTER TABLE ... ENABLE KEYS} benutzt werden, um fehlende
Indexe wieder zu erzeugen. Weil MySQL das mit Algorithmen durchführt, die
viel schneller sind als das Einfügen von Schlüsseln nacheinander, kann das
Abschalten von Schlüsseln bei Masseneinfügeoperationen erheblich
Geschwindigkeitsvorteile bringen.

@item
@code{create_definition}-Klauseln benutzen dieselbe Syntax für @code{ADD}
und @code{CHANGE} wie bei @code{CREATE TABLE}.  Beachten Sie, dass diese
Syntax den Spaltenname beinhaltet, nicht nur den Spaltentyp.
@c German FIX unsplit @xref
@xref{CREATE TABLE, , @code{CREATE TABLE}}.

@item
Sie können eine Spalte mit einer @code{CHANGE alter_spalten_name
create_definition}-Klausel umbenennen. Um das zu tun, geben Sie den alten
und den neuen Spaltennamen und den Typ an, den die Spalte momentan hat. Um
beispielsweise eine @code{INTEGER}-Spalte von @code{a} nach @code{b}
umzubenennen, tun Sie folgendes:

@example
mysql> ALTER TABLE t1 CHANGE a b INTEGER;
@end example

Wenn Sie einen Spaltentyp, nicht aber den Namen ändern wollen, benötigt
@code{CHANGE} dennoch zwei Spaltennamen, selbst wenn sie dieselben sind.
Beispiel:

@example
mysql> ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
@end example

Ab MySQL-Version 3.22.16a können Sie jedoch auch @code{MODIFY} benutzen, um
einen Spaltentyp ohne Umbenennung zu ändern:

@example
mysql> ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
@end example

@item
Wenn Sie @code{CHANGE} oder @code{MODIFY} benutzen, um eine Spalte zu
kürzen, für die es einen Index auf einem Teil der Spalte gibt (wenn Sie zum
Beispiel einen Index auf den ersten 10 Zeichen einer @code{VARCHAR}-Spalte
haben), können Sie die Spalte nicht kürzer als die Anzahl von Zeichen
machen, die indiziert sind.

@item
Wenn Sie versuchen, einen Spaltentyp mit @code{CHANGE} oder @code{MODIFY}
zu ändern, versucht MySQL, Daten so umzuwandeln, dass sie so gut wie
möglich zum neuen Typ passen.

@item
AB MySQL-Version 3.22 können Sie @code{FIRST} oder @code{ADD ... AFTER
spalten_name} benutzen, um eine Spalte an einer bestimmten Position
innerhalb einer Tabellenzeile einzufügen. Vorgabemäßig wird die Spalte am
Ende hinzugefügt.

@findex ALTER COLUMN
@item
@code{ALTER COLUMN} gibt einen Vorgabewert für eine Spalte an oder entfernt
den alten Vorgabewert. Wenn der alte Vorgabewert entfernt wird und die
Spalte @code{NULL} sein darf, ist der neue Vorgabewert @code{NULL}. Wenn
die Spalte nicht @code{NULL} sein darf, weist MySQL einen Vorgabewert zu,
wie in @ref{CREATE TABLE, , @code{CREATE TABLE}} beschrieben.

@findex DROP INDEX
@item
@code{DROP INDEX} entfernt einen Index. Das ist eine MySQL-Erweiterung zu
ANSI-SQL92. @xref{DROP INDEX}.

@item
Wenn Spalten aus einer Tabelle gelöscht werden, werden sie auch aus
jeglichen Indexen entfernt, deren Teil sie sind. Wenn alle Spalten, aus
denen ein Index besteht, gelöscht werden, wird der Index ebenfalls
gelöscht.

@item
Wenn eine Tabelle nur eine Spalte enthält, kann die Spalte nicht gelöscht
werden. Wenn Sie beabsichtigen, die Tabelle zu entfernen, benutzen Sie
statt dessen @code{DROP TABLE}.

@findex DROP PRIMARY KEY
@item
@code{DROP PRIMARY KEY} löscht den Primärschlüssel. Wenn es keinen solchen
gibt, löscht es den ersten @code{UNIQUE}-Index in der Tabelle. (MySQL
kennzeichnet den ersten @code{UNIQUE}-Schlüssel als @code{PRIMARY KEY},
wenn @code{PRIMARY KEY} nicht explizit angegeben wurde.)

@findex UNIQUE
@findex PRIMARY KEY
Wenn Sie einen @code{UNIQUE INDEX} oder @code{PRIMARY KEY} zu einer Tabelle
hinzufügen, wird dieser vor jedem Nicht-@code{UNIQUE}-Index gespeichert, so
dass MySQL doppelte Schlüsseleinträge so früh wie möglich feststellen kann.

@findex ORDER BY
@item
@code{ORDER BY} gestattet Ihnen, eine Tabelle mit Zeilen in einer
bestimmten Reihenfolge zu erzeugen. Beachten Sie, dass die Tabelle nach
INSERTs und DELETEs nicht in dieser Reihenfolge verbleibt. In einigen
Fällen kann es das Sortieren für MySQL erleichtern, wenn die Tabelle nach
der Spalte geordnet ist, nach der Sie sie später ordnen wollen. Diese
Option ist hauptsächlich nützlich, wenn Sie wissen, dass Sie die Zeilen
meistens in einer bestimmten Reihenfolge abfragen werden. Wenn Sie diese
Option nach großen Änderungen in der Tabelle benutzen, können Sie
möglicherweise eine höhere Performance erzielen.

@findex ALTER TABLE
@item
Wenn Sie @code{ALTER TABLE} auf einer @code{MyISAM}-Tabelle benutzen,
werden alle nicht eindeutigen Indexe in einem separaten Stapellauf erzeugt
(wie bei @code{REPAIR}). Das sollte @code{ALTER TABLE} viel schneller
machen, wenn Sie viele Indexe haben.

@item
Ab @strong{MySQL 4.0} kann dies explizit aktiviert werden. @code{ALTER
TABLE ... DISABLE KEYS} veranlasst MySQL, mit der Aktualisierung nicht
eindeutiger Indexe für @code{MyISAM}-Tabellen aufzuhören. @code{ALTER TABLE
... ENABLE KEYS} sollte dann benutzt werden, um fehlende Indexe wieder zu
erzeugen. Weil MySQL das mit Algorithmen durchführt, die viel schneller
sind als das Einfügen von Schlüsseln nacheinander, kann das Abschalten von
Schlüsseln bei Masseneinfügeoperationen erheblich Geschwindigkeitsvorteile
bringen.

@item
@findex mysql_info()
Mit der C-API-Funktion @code{mysql_info()} können Sie herausfinden, wie
viele Datensätze kopiert wurden und (wenn @code{IGNORE} benutzt wird) wie
viele Datensätze aufgrund der Duplizierung eindeutiger Schlüsselwerte
gelöscht wurden.

@item
@cindex Fremdschlüssel
@cindex Referenzen
Die @code{FOREIGN KEY}-, @code{CHECK}- und @code{REFERENCES}-Klauseln
machen nichts. Die Syntax für sie steht nur aus Kompatibilitätsgründen
bereit, um das Portieren von Code von anderen SQL-Servern zu erleichtern
und um Applikationen laufen zu lassen, die Tabellen mit Referenzen
erzeugen.
@c German FIX old ref was @xref{Fehlende Funktionen}.
@xref{ANSI diff Foreign Keys}.
@end itemize

Hier ist ein Beispiel, das einige der Anwendungsfälle von @code{ALTER
TABLE} zeigt. Wir fangen mit einer Tabelle @code{t1} an, die wie folgt
erzeugt wird:

@example
mysql> CREATE TABLE t1 (a INTEGER,b CHAR(10));
@end example

Um die Tabelle von @code{t1} nach @code{t2} umzubenennen, geben Sie ein:

@example
mysql> ALTER TABLE t1 RENAME t2;
@end example

Um Spalte @code{a} von @code{INTEGER} nach @code{TINYINT NOT NULL} zu
ändern (der Name bleibt derselbe) und Spalte @code{b} von @code{CHAR(10)}
nach @code{CHAR(20)} zu ändern und gleichzeitig von @code{b} nach @code{c}
umzubenennen, geben Sie ein:

@example
mysql> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);
@end example

Jetzt wird eine @code{TIMESTAMP}-Spalte namens @code{d} hinzugefügt:

@example
mysql> ALTER TABLE t2 ADD d TIMESTAMP;
@end example

Nunmehr erzeugen wir einen Index auf Spalte @code{d} und machen Spalte
@code{a} zum Primärschlüssel:

@example
mysql> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);
@end example

Wir entfernen Spalte @code{c}:

@example
mysql> ALTER TABLE t2 DROP COLUMN c;
@end example

Und fügen eine neue @code{AUTO_INCREMENT}-Ganzzahl-Spalte namens @code{c}
hinzu:

@example
mysql> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
           ADD INDEX (c);
@end example

Beachten Sie, dass wir @code{c} indiziert haben, weil
@code{AUTO_INCREMENT}-Spalten indiziert sein müssen, und auch, dass wir
@code{c} als @code{NOT NULL} deklariert haben, weil indizierte Spalten
nicht @code{NULL} sein dürfen.

Wenn Sie eine @code{AUTO_INCREMENT}-Spalte hinzufügen, werden automatisch
Spaltenwerte mit Zahlenfolgen eingefügt. Sie können die erste Zahl setzen,
indem Sie @code{SET INSERT_ID=#} vor @code{ALTER TABLE} ausführen oder
indem Sie die @code{AUTO_INCREMENT = #}-Tabellenoption benutzen.
@xref{SET OPTION}.

Wenn Sie bei MyISAM-Tabellen nicht die @code{AUTO_INCREMENT}-Spalte ändern,
ist die Folgezahl davon nicht betroffen. Wenn Sie eine
@code{AUTO_INCREMENT}-Spalte löschen und dann eine weitere
@code{AUTO_INCREMENT}-Spalte hinzufügen, fangen die Zahlen wieder bei 1 an.

@xref{ALTER TABLE problems}.


@node RENAME TABLE, DROP TABLE, ALTER TABLE, Data Definition
@c German node RENAME TABLE
@subsection @code{RENAME TABLE}-Syntax

@findex RENAME TABLE

@example
RENAME TABLE tabelle TO neue_tabelle[, tabelle2 TO neue_tabelle2,...]
@end example

Das Umbenennen wird atomisch durchgeführt, was heißt, dass kein anderer
Thread auf die Tabelle(n) zugreifen kann, während umbenannt wird. Das
ermöglicht, eine Tabelle durch eine leere zu ersetzen:

@example
CREATE TABLE neue_tabelle (...);
RENAME TABLE alte_tabelle TO datensicherung_tabelle, neue_tabelle TO alte_tabelle;
@end example

Das Umbenennen wird von links nach rechts durchgeführt, was bedeutet, dass
Sie beim Vertauschen zweier Tabellennamen folgendes tun können:

@example
RENAME TABLE alte_tabelle    TO datensicherung_tabelle,
             neue_tabelle    TO alte_tabelle,
             datensicherung_tabelle TO neue_tabelle;
@end example

Solange zwei Datenbanken auf derselben Platte liegen, können Sie auch von
einer Datenbank in eine andere umbenennen:

@example
RENAME TABLE aktuelle_datenbank.tabelle TO andere_datenbank.tabelle;
@end example

Wenn Sie @code{RENAME} ausführen, dürfen Sie keine gesperrten Tabellen oder
aktive Transaktionen haben. Ausserdem benötigen Sie die @code{ALTER}- und
@code{DROP}-Berechtigungen für die Original-Tabelle und die @code{CREATE}-
und @code{INSERT}-Berechtigungen auf die neue Tabelle.

Wenn beim Umbenennen mehrfacher Tabellen Fehler auftreten, führt MySQL ein
entgegengesetztes Umbenennen aller umbenannten Tabellen durch, um alles
wieder in den Ausgangszustand zu versetzen.


@node DROP TABLE, CREATE INDEX, RENAME TABLE, Data Definition
@c German node DROP TABLE
@subsection @code{DROP TABLE}-Syntax

@findex DROP TABLE

@example
DROP TABLE [IF EXISTS] tabelle [, tabelle,...] [RESTRICT | CASCADE]
@end example

@code{DROP TABLE} entfernt eine oder mehrere Tabellen. Alle Tabellendaten
und die Tabellendefinition werden @emph{zerstört}, seien Sie daher
@strong{vorsichtig} mit diesem Befehl!

Ab MySQL-Version 3.22 können Sie die Schlüsselwörter @code{IF EXISTS}
benutzen, um Fehler zu vermeiden, die auftreten, wenn Tabellen nicht
existieren.

@code{RESTRICT} und @code{CASCADE} sind wegen leichterer Portierung
zugelassen. Momentan tun sie nichts.

@strong{HINWEIS}: @code{DROP TABLE} ist nicht transaktionssicher und führt
automatisch jegliche aktiven Transaktionen zuende.


@node CREATE INDEX, DROP INDEX, DROP TABLE, Data Definition
@c German node CREATE INDEX
@subsection @code{CREATE INDEX}-Syntax

@findex CREATE INDEX

@cindex Indexe
@cindex Indexe, mehrteilige
@cindex mehrteilige Indexe

@example
CREATE [UNIQUE|FULLTEXT] INDEX index_name ON tabelle (spalten_name[(laenge)],... )
@end example

Das @code{CREATE INDEX}-Statement macht vor MySQL-Version 3.22 nichts. Ab
Version 3.22 ist @code{CREATE INDEX} auf ein @code{ALTER TABLE}-Statement
gemappt, um Indexe zu erzeugen. @xref{ALTER TABLE, , @code{ALTER TABLE}}.

Normalerweise erzeugen Sie alle Indexe auf eine Tabelle zur Zeit, wo die
Tabelle selbst mit @code{CREATE TABLE} erzeugt wird.
@c German FIX unsplit @xref
@xref{CREATE TABLE, ,@code{CREATE TABLE}}.
@code{CREATE INDEX} gestattet, bestehenden Tabellen
Indexe hinzuzufügen.

A Spaltenliste der Form @code{(spalte1,spalte2,...)} erzeugt einen
mehrspaltigen Index. Die Indexwerte werden durch Verkettung der Werte der
angegebenen Spalten erzeugt.

Bei @code{CHAR}- und @code{VARCHAR}-Spalten können Indexe, die nur einen
Teil einer Spalte benutzen, mit der @code{spalten_name(laenge)}-Syntax
erzeugt werden. (Bei @code{BLOB}- und @code{TEXT}-Spalten ist die
Längenangabe erforderlich.) Unten stehendes Statement zeigt, wie ein Index
erzeugt wird, der die ersten 10 Zeichen der @code{name}-Spalte benutzt:

@example
mysql> CREATE INDEX teil_von_name ON kunde (name(10));
@end example

Weil sich die meisten Namen üblicherweise in den ersten 10 Zeichen
unterscheiden, sollte dieser Index nicht viel langsamer sein, als wenn der
Index aus der gesamten @code{name}-Spalte erzeugt worden wäre. Die
Benutzung von Teilspalten für Indexe kann die Index-Datei auch viel kleiner
machen, was viel Speicherplatz sparen und zusätzlich
@code{INSERT}-Operationen beschleunigen kann!

Beachten Sie, dass Sie einen Index auf eine Spalte, die @code{NULL}-Werte
haben darf, oder auf eine @code{BLOB}/@code{TEXT}-Spalte erst ab
MySQL-Version 3.23.2 und nur beim @code{MyISAM}-Tabellentyp erzeugen
können.

Weitere Informationen darüber, wie MySQL Indexe benutzt, finden Sie unter
@ref{MySQL indexes, , MySQL-Indexe}.

@code{FULLTEXT}-Indexe können nur @code{VARCHAR}- und @code{TEXT}-Spalten
indexieren und funktionieren nur bei @code{MyISAM}-Tabellen.
@code{FULLTEXT}-Indexe sind ab MySQL-Version 3.23.23 verfügbar.
@ref{Fulltext Search}.


@node DROP INDEX,  , CREATE INDEX, Data Definition
@c German node DROP INDEX
@subsection @code{DROP INDEX}-Syntax

@findex DROP INDEX

@example
DROP INDEX index_name ON tabelle
@end example

@code{DROP INDEX} löscht den Index namens @code{index_name} aus der Tabelle
@code{tabelle}. @code{DROP INDEX} macht vor MySQL-Version 3.22 nichts. Ab
Version 3.22 ist @code{DROP INDEX} auf ein @code{ALTER TABLE}-Statement
gemappt, um den Index zu löschen. @xref{ALTER TABLE, , @code{ALTER TABLE}}.


@node Basic User Commands, Transactional Commands, Data Definition, Reference
@c German node Grundlegende Benutzerbefehle
@section Grundlegende Befehle des MySQL-Dienstprogramms für Benutzer



@menu
* USE::                         
* DESCRIBE::                    
@end menu

@node USE, DESCRIBE, Basic User Commands, Basic User Commands
@c German node USE
@subsection @code{USE}-Syntax

@findex USE

@example
USE datenbank
@end example

Das @code{USE datenbank}-Statement weist MySQL an, @code{datenbank} als
vorgabemäßige Datenbank für nachfolgende Anfragen zu benutzen. Die
Datenbank bleibt die aktuelle, entweder bis zum Ende der Sitzung, oder bis
ein weiteres @code{USE}-Statement abgesetzt wird:

@example
mysql> USE datenbank1;
mysql> SELECT count(*) FROM tabelle;      # wählt aus von datenbank1.tabelle
mysql> USE datenbank2;
mysql> SELECT count(*) FROM tabelle;      # wählt aus von datenbank2.tabelle
@end example

Wenn Sie eine bestimmte Datenbank mit dem @code{USE}-Statement zu aktuellen
machen, heißt das nicht, dass Sie nicht auf Tabellen in anderen
Datenbanken zugreifen können. Das unten stehende Beispiel zeigt den Zugriff
auf die @code{autor}-Tabelle in der @code{datenbank1}-Datenbank und auf
die @code{herausgeber}-Tabelle in der @code{datenbank2}-Datenbank:

@example
mysql> USE datenbank1;
mysql> SELECT autor_name,herausgeber_name FROM autor,datenbank2.herausgeber
           WHERE autor.herausgeber_id = datenbank2.herausgeber.herausgeber_id;
@end example

@cindex Sybase Kompatibilität
@cindex Kompatibilität, mit Sybase
The @code{USE}-Statement wird für die Sybase-Kompatibilität zur Verfügung
gestellt.


@node DESCRIBE,  , USE, Basic User Commands
@c German node DESCRIBE
@subsection @code{DESCRIBE}-Syntax (Informationen über Spalten erhalten)

@findex DESC
@findex DESCRIBE

@example
@{DESCRIBE | DESC@} tabelle @{spalten_name | platzhalter@}
@end example

@code{DESCRIBE} ist ein Kürzel für @code{SHOW COLUMNS FROM}.
@xref{SHOW DATABASE INFO}.

@code{DESCRIBE} stellt Informationen über die Spalten einer Tabelle bereit.
@code{spalten_name} kann ein Spaltenname oder eine Zeichenkette sein, die
die SQL-@samp{%}- und -@samp{_}-Platzhalterzeichen enthält.

Wenn die Spaltentypen sich von dem unterscheiden, was Sie auf der Grundlage
eines @code{CREATE TABLE}-Statements erwartet hätten, beachten Sie, dass
MySQL manchmal Spaltentypen ändert.  @xref{Silent column changes}.

@cindex Oracle-Kompatibilität
@cindex Kompatibilität, mit Oracle
Dieses Statement wird für die Oracle-Kompatibilität zur Verfügung gestellt.

Das @code{SHOW}-Statement stellt ähnliche Informationen bereit.
@xref{SHOW, , @code{SHOW}}.


@node Transactional Commands, Fulltext Search, Basic User Commands, Reference
@c German node Transaktionale Befehle
@section Transaktionale und Sperrbefehle von MySQL



@menu
* COMMIT::                      
* LOCK TABLES::                 
* SET TRANSACTION::             
@end menu

@node COMMIT, LOCK TABLES, Transactional Commands, Transactional Commands
@c German node COMMIT
@subsection @code{BEGIN/COMMIT/ROLLBACK}-Syntax

@findex BEGIN
@findex COMMIT
@findex ROLLBACK

Vorgabemäßig läuft MySQL im @code{autocommit}-Modus. Das heißt, dass
MySQL eine Aktualisierung auf Platte speichert, sobald Sie eine
Aktualisierung ausführen.

Wenn Sie transaktionssichere Tabellen (wie @code{InnoDB} oder @code{BDB} )
benutzen, können Sie MySQL mit folgendem Befehl in den
Nicht-@code{autocommit}-Modus setzen:

@example
SET AUTOCOMMIT=0
@end example

Danach müssen Sie @code{COMMIT} benutzen, um Ihre Änderungen auf Platte zu
sichern, oder @code{ROLLBACK}, wenn Sie die Änderungen verwerfen wollen,
die Sie seit dem Beginn der Transaktion gemacht haben.

Wenn Sie für eine Reihe von Statements zum @code{AUTOCOMMIT}-Modus
umschalten wollen, können Sie das @code{BEGIN}- oder @code{BEGIN
WORK}-Statement benutzen:

@example
BEGIN;
SELECT @@A:=SUM(gehalt) FROM tabelle1 WHERE type=1;
UPDATE tabelle2 SET zusammenfassung=@@A WHERE type=1;
COMMIT;
@end example

Beachten Sie, dass bei der Benutzung nicht transaktionssicher Tabellen die
Änderungen dennoch sofort gespeichert werden, unabhängig vom Status des
@code{autocommit}-Modus.

Wenn Sie @code{ROLLBACK} bei der Aktualisierung einer nicht transaktionalen
Tabelle ausführen, erhalten Sie einen Fehler
(@code{ER_WARNING_NOT_COMPLETE_ROLLBACK}) als Warnung. Alle
transaktionssicheren Tabellen werden zurückgesetzt, aber nicht
transaktionale Tabelle ändern sich nicht.

Wenn Sie @code{BEGIN} oder @code{SET AUTOCOMMIT=0} benutzen, sollten Sie
die MySQL-Binär-Log-Datei für Datensicherungen benutzen statt der älteren
Update-Log-Datei. Transaktionen werden in der Binär-Log-Datei in einem
Stück gespeichert, beim @code{COMMIT}, um sicherzustellen, dass
Transaktionen, die zurückgesetzt werden (Rollback), nicht gespeichert
werden. @xref{Binary log}.

Folgende Befehle beenden automatisch eine Transaktion (als ob Sie ein
@code{COMMIT} vor der Ausführung des Befehls ausgeführt hätten:

@multitable @columnfractions .33 .33 .33
@item @code{ALTER TABLE} @tab @code{BEGIN} @tab @code{CREATE INDEX}
@item @code{DROP DATABASE} @tab @code{DROP TABLE} @tab @code{RENAME TABLE}
@item @code{TRUNCATE}
@end multitable

@c German FIX changed @xref to @xref
Sie können die Isolationsebene (Isolation Level) für Transaktionen mit
@code{SET TRANSACTION ISOLATION LEVEL ...} @ref{SET TRANSACTION} ändern.


@node LOCK TABLES, SET TRANSACTION, COMMIT, Transactional Commands
@c German node LOCK TABLES
@subsection @code{LOCK TABLES/UNLOCK TABLES}-Syntax

@findex LOCK TABLES
@findex UNLOCK TABLES

@example
LOCK TABLES tabelle [AS alias] @{READ | [READ LOCAL] | [LOW_PRIORITY] WRITE@}
            [, tabelle @{READ | [LOW_PRIORITY] WRITE@} ...]
...
UNLOCK TABLES
@end example

@code{LOCK TABLES} sperrt Tabellen für den aktuellen Thread. @code{UNLOCK
TABLES} hebt alle Sperren auf, die vom aktuellen Thread veranlasst wurden.
Alle Tabellen, die durch den aktuellen Thread gesperrt sind, werden
automatisch entsperrt, wenn der Thread ein weiteres @code{LOCK TABLES}
absetzt oder wenn die Verbindung zum Server geschlossen wird.

Die wichtigsten Gründe für die Benutzung von @code{LOCK TABLES} sind die
Emulation von Transaktionen oder um mehr Geschwindigkeit bei der
Aktualisierung von Tabellen zu erhalten. Das wird später detaillierter
erläutert.

Wenn ein Thread eine @code{READ}-Sperre auf eine Tabelle erlangt, kann
dieser Thread (und alle anderen Threads) nur aus der Tabelle lesen. Wenn
ein Thread eine @code{WRITE}-Sperre auf eine Tabelle erlangt, kann nur der
Thread, der die Sperre veranlasst hat, @code{READ} oder @code{WRITE} auf
der Tabelle durchführen. Andere Threads werden blockiert.

Der Unterschied zwischen @code{READ LOCAL} und @code{READ} ist, dass
@code{READ LOCAL} nicht kollidierende @code{INSERT}-Statements während der
Dauer der Sperre zuläßt. Das kann jedoch nicht benutzt werden, wenn Sie
Datenbankdateien ausserhalb von MySQL bearbeiten, während die Sperre aktiv
ist.

Wenn Sie @code{LOCK TABLES} benutzen, müssen Sie alle Tabellen sperren, die
Sie benutzen werden, und Sie müssen denselben Alias benutzen, den Sie in
Ihren Anfragen benutzen werden! Wenn Sie eine Tabelle in einer Anfrage
mehrfach (mit Aliasen) benutzen, müssen Sie für jeden Alias eine Sperre
machen!

@code{WRITE}-Sperren haben normalerweise höhere Priorität als
@code{READ}-Sperren, um sicherzustellen, dass Aktualisierungen so früh wie
möglich bearbeitet werden. Dass heißt, wenn ein Thread eine
@code{READ}-Sperre erlangt und dann ein anderer Thread eine
@code{WRITE}-Sperre verlangt, dass nachfolgende @code{READ}-Sperrenanfragen
warten, bis der @code{WRITE}-Thread die Sperre erhalten und freigegeben
hat. Sie können @code{LOW_PRIORITY WRITE}-Sperren benutzen, um anderen
Threads zu gestatten, @code{READ}-Sperren zu erlangen, während der Thread
auf die @code{WRITE}-Sperre wartet. Sie sollten nur dann @code{LOW_PRIORITY
WRITE}-Sperren benutzen, wenn Sie sicher sind, dass es irgendwann eine Zeit
gibt, in der kein anderer Thread eine @code{READ}-Sperre haben wird.

@code{LOCK TABLES} funktioniert wie folgt:
@enumerate
@item
Sortiert alle Tabellen, die gesperrt werden sollen, in einer intern
definierten Reihenfolge (aus Benutzersicht ist die Reihenfolge
undefiniert).
@item
Wenn eine Tabelle mit einer Lese- und einer Schreibsperre gesperrt ist,
wird die Schreibsperre vor die Lesesperre platziert.
@item
Sperrt eine Tabelle nach der anderen, bis der Thread alle Sperren erhalten
hat.
@end enumerate

Diese Methode stellt sicher, dass Tabellensperren blockierungsfrei ist. Bei
diesem Schema gibt es jedoch ein paar weitere Dinge, derer man sich bewusst
sein muss:

Wenn Sie eine @code{LOW_PRIORITY_WRITE}-Sperre für eine Tabelle benutzen,
heißt das, dass MySQL auf diese bestimmte Sperre wartet, bis es keinen
Thread gibt, der eine @code{READ}-Sperre will. Wenn der Thread die
@code{WRITE}-Sperre erhalten hat und darauf wartet, die Sperre für die
nächste Tabelle in der Tabellensperrliste zu erhalten, warten alle anderen
Threads darauf, dass die @code{WRITE}-Sperre aufgehoben wird. Wenn das bei
Ihrer Applikation zu ernsthaften Problemen führt, sollten Sie in Betracht
ziehen, einige Ihrer Tabelle in transaktionssichere Tabelle umzuwandeln.

Es ist sicher, einen Thread mit @code{KILL} zu killen, der auf eine
Tabellensperre wartet. @xref{KILL}.

Beachten Sie, dass Sie @strong{NICHT} irgend welche Tabellen sperren
sollten, die Sie mit @code{INSERT DELAYED} benutzen. Das liegt darin, dass
in diesem Fall das @code{INSERT} von einem separaten Thread durchgeführt
wird.

Normalerweise müssen Sie Tabellen nicht sperren, weil alle einzelnen
@code{UPDATE}-Statements atomisch sind. Kein anderer Thread kann mit einem
aktuell ausgeführten SQL-Statement in die Quere kommen. Es gibt dennoch
einige Fällen, in denen es wünschenswert sein kann, Tabellen zu sperren:

@itemize @bullet
@item
Wenn Sie viele Operationen auf einer großen Zahl von Tabellen laufen
lassen wollen, ist es viel schneller, die Tabellen zu sperren, die Sie
benutzen werden. Der Nachteil besteht natürlich darin, dass kein anderer
Thread eine @code{READ}-gesperrte Tabelle aktualisieren und kein anderer
Thread eine @code{WRITE}-gesperrte Tabelle lesen kann.

Der Grund, dass einiges mit @code{LOCK TABLES} schneller geht, liegt darin,
dass MySQL den Schlüssel-Cache für die gesperrten Tabellen nicht auf Platte
zurückschreibt (flush), bis @code{UNLOCK TABLES} aufgerufen wird
(normalerweise wird der Schlüssel-Cache nach jedem SQL-Statement auf Platte
zurückgeschrieben). Das erhöht die Geschwindigkeit bei den Operationen
INSERT / UPDATE / DELETE bei @code{MyISAM}-Tabellen.
@item
Wenn Sie einen Tabellen-Handler in MySQL benutzen, der keine Transaktionen
unterstützt, müssen Sie @code{LOCK TABLES} benutzen, wenn Sie sicherstellen
wollen, dass kann anderer Thread zwischen einem @code{SELECT} und einem
@code{UPDATE} dazwischen kommen kann. Das unten stehende Beispiel erfordert
@code{LOCK TABLES}, um sicher ausgeführt zu werden:

@example
mysql> LOCK TABLES trans READ, kunde WRITE;
mysql> select sum(wert) from trans where kunde_id=irgendeine_id;
mysql> update kunde set gesamt_wert=summe_aus_vorherigem_statement
           where kunde_id=irgendeine_id;
mysql> UNLOCK TABLES;
@end example

Ohne @code{LOCK TABLES} besteht die Möglichkeit, dass ein anderer Thread
eine neue Zeile in die @code{trans}-Tabelle einfügt, zwischen der
Ausführung des @code{SELECT}- und des @code{UPDATE}-Statements.
@end itemize

Wenn Sie inkrementelle Updates (@code{UPDATE kunde SET
wert=wert+neuer_wert}) oder die @code{LAST_INSERT_ID()}-Funktion benutzen,
können Sie @code{LOCK TABLES} in vielen Fällen vermeiden.

Einige Problemfälle können Sie auch lösen, indem Sie die Sperrfunktionen
auf Benutzerebene @code{GET_LOCK()} und @code{RELEASE_LOCK()} benutzen.
Diese Sperren werden in einer Hash-Tabelle im Server gespeichert und sind
mit @code{pThread_mutex_lock()} und @code{pThread_mutex_unlock()} für die
Erzielung höherer Geschwindigkeit implementiert.
@xref{Miscellaneous functions}.

Siehe @ref{Internal locking} wegen weiterer Informationen über
Sperrmethoden.

Sie können alle Tabellen in allen Datenbanken mit Lesesperren sperren, und
zwar mit dem @code{FLUSH TABLES WITH READ LOCK}-Befehl. @xref{FLUSH}. Das
ist eine sehr bequeme Möglichkeit, Datensicherungen zu erhalten, wenn Sie
ein Dateisystem wie Veritas haben, dass Schnappschüsse im Zeitverlauf
aufnehmen kann.

@strong{HINWEIS}: @code{LOCK TABLES} ist nicht transaktionssicher und
schickt automatisch jegliche aktiven Transaktionen ab (Commit), bevor es
versucht, die Tabellen zu sperren.


@node SET TRANSACTION,  , LOCK TABLES, Transactional Commands
@c German node SET TRANSACTION
@subsection @code{SET TRANSACTION}-Syntax

@findex ISOLATION LEVEL

@example
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
[READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE]
@end example

Setzt die Transaktionsisolationsebene für die globale, gesamte Sitzung oder
für die nächste Transaktion.

Das vorgabemäßige Verhalten ist das Setzen der Isolationsebene für die
nächste (nicht angefangene) Transaktion.

Wenn Sie die @code{GLOBAL}-Berechtigung setzen, betrifft das alle neu
erzeugten Threads. Sie benötigen dafür die @code{PROCESS}-Berechtigung.

Wenn Sie die @code{SESSION}-Berechtigung setzen, betrifft das die folgenden
und alle zukünftigen Transaktionen.

Sie können die vorgabemäßige Isolationsebene für @code{mysqld} mit
@code{--transaction-isolation=...} setzen. @xref{Command-line options}.


@node Fulltext Search, Query Cache, Transactional Commands, Reference
@c German node Volltextsuche
@section MySQL-Volltextsuche

@cindex Suchen, Volltext
@cindex Volltextsuche
@cindex FULLTEXT

Ab Version 3.23.23 bietet MySQL Unterstützung für Volltext-Indexierung und
-Suche. Volltext-Indexe sind in MySQL Indexe vom Typ @code{FULLTEXT}. 
@code{FULLTEXT}-Indexe können von @code{VARCHAR}- und @code{TEXT}-Spalten
zur Zeit von @code{CREATE TABLE} erzeugt werden oder später mit @code{ALTER
TABLE} oder @code{CREATE INDEX} hinzugefügt werden. Bei großen Datenmengen
ist es viel schneller, einen @code{FULLTEXT}-Index mit @code{ALTER TABLE}
(oder @code{CREATE INDEX}) hinzuzufügen, als Zeilen in eine leere Tabelle
mit einem @code{FULLTEXT}-Index einzufügen.

Die Volltextsuche wird mit der @code{MATCH}-Funktion durchgeführt.

@example
mysql> CREATE TABLE artikel (
    ->   id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY, 
    ->   titel VARCHAR(200),
    ->   artikeltext TEXT,
    ->   FULLTEXT (titel,artikeltext)
    -> );
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO artikel VALUES
    -> (0,'MySQL-Tutorial', 'DBMS steht für DataBase-Management ...'),
    -> (0,'Wie man MySQL effizient einsetzt', 'Nachdem Sie ...'),
    -> (0,'MySQL optimieren','In diesem Tutorial wird gezeigt, wie ...'),
    -> (0,'1001 MySQL-Tricks','1. Lassen Sie mysqld nie als root laufen. 2. Normalisieren ...'),
    -> (0,'MySQL vs. YourSQL', 'Im folgenden Datenbankvergleich ...'),
    -> (0,'MySQL-Sicherheitsaspekte', 'Wenn er korrekt konfiguriert ist, ist MySQL ...');
Query OK, 5 rows affected (0.00 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> SELECT * FROM artikel WHERE MATCH (titel,artikeltext) AGAINST ('Datenbank');
+----+-------------------+---------------------------------------------+
| id | titel             | artikeltext                                 |
+----+-------------------+---------------------------------------------+
|  5 | MySQL vs. YourSQL | Im folgenden Datenbankvergleich ...         |
|  1 | MySQL-Tutorial    | DBMS steht für DataBase-Management ...      |
+----+-------------------+---------------------------------------------+
2 rows in set (0.00 sec)
@end example

Die Funktion @code{MATCH} prüft eine natürlichsprachige Anfrage gegen
(@code{AGAINST}) eine Textsammlung (einfach ein Satz von Spalten, der vom
@code{FULLTEXT}-Index abgedeckt wird). Für jede Zeile in einer Tabelle gibt
sie eine Relevanz zurück - ein Ähnlichkeitsmaß zwischen dem Text in dieser
Zeile (in den Spalten, die Teil der Textsammlung sind) und der Anfrage.
Wenn sie in einer @code{WHERE}-Klausel benutzt wird (siehe Beispiel oben),
werden die zurückgegebenen Zeilen automatisch nach absteigender Relevanz
sortiert. Die Relevanz ist eine nicht negative Fließkommazahl. 0 Relevanz
bedeutet keine Ähnlichkeit. Die Relevanz wird auf der Grundlage der Anzahl
von Wörtern in der Zeile, der Anzahl eindeutiger Wörter in dieser Zeile,
der Gesamtzahl von Wörtern in der Textsammlung und der Anzahl von
Dokumenten (Zeilen) berechnet, die ein bestimmtes Wort enthalten.

Das obige Beispiel ist ein grundlegendes Beispiel der Benutzung der
@code{MATCH}-Funktion. Die Zeilen werden nach absteigender Relevanz
zurückgegeben.

@example
mysql> SELECT id,MATCH (titel,artikeltext) AGAINST ('Tutorial') FROM artikel;
+----+------------------------------------------------+
| id | MATCH (titel,artikeltext) AGAINST ('Tutorial') |
+----+------------------------------------------------+
|  1 |                               0.64840710366884 |
|  2 |                                              0 |
|  3 |                               0.66266459031789 |
|  4 |                                              0 |
|  5 |                                              0 |
|  6 |                                              0 |
+----+------------------------------------------------+
5 rows in set (0.00 sec)
@end example

Dieses Beispiel zeigt, wie man Relevanzen abruft. Weil weder die
@code{WHERE}- noch die @code{ORDER BY}-Klausel vorhanden sind, werden die
Zeilen unsortiert zurückgegeben.

@example
mysql> SELECT id, artikeltext, MATCH (titel,artikeltext) AGAINST (
    -> 'Sicherheits-Implikationen, wenn Sie MySQL als root laufen lassen') AS rang
    -> FROM artikel WHERE MATCH (titel,artikeltext) AGAINST
    -> ('Sicherheits-Implikationen, wenn Sie MySQL als root laufen lassen');
+----+----------------------------------------------------------------+-----------------+
| id | artikeltext                                                    | rang            |
+----+----------------------------------------------------------------+-----------------+
|  4 | 1. Lassen Sie mysqld nie als root laufen. 2. Normalisieren ... | 1.5055546709332 |
|  6 | Wenn er korrekt konfiguriert ist, ist MySQL ...                |   1.31140957288 |
+----+----------------------------------------------------------------+-----------------+
2 rows in set (0.00 sec)
@end example

Das ist ein komplexeres Beispiel - die Anfrage gibt die Relevanz zurück und
sortiert die Zeilen auch noch nach absteigender Relevanz. Um das zu
erzielen, müssen Sie @code{MATCH} zweimal angeben. Beachten Sie, dass das
keinen zusätzlichen Overhead verursacht, weil der MySQL-Optimierer bemerkt,
dass diese zwei @code{MATCH}-Aufrufe identisch sind und daher den Code für
die Volltextsuche nur einmal aufruft.

MySQL benutzt einen sehr einfachen Parser, um Text in Wörter zu zerlegen.
Ein ``Wort'' ist jede Folge von Buchstaben, Zahlen, @samp{'} und @samp{_}.
Jedes ``Wort'', das in der Liste der Stopwords vorkommt oder einfach nur
zu kurz ist (3 Zeichen oder weniger), wird ignoriert.

Jedes korrekte Wort in der Textsammlung und in der Anfrage wird nach seiner
Signifikanz in der Anfrage oder der Textsammlung gewichtet. Daher hat ein
Wort, dass in vielen Dokumenten vorkommt, ein geringeres Gewicht (und kann
sogar 0 Gewicht haben), weil es in dieser bestimmten Textsammlung einen
geringen semantischen Wert hat. Ansonsten, wenn das Wort selten vorkommt,
erhält es ein höheres Gewicht. Die Gewichte der Wörter werden anschließend
kombiniert, um die Relevanz der Zeile zu berechnen.

Solch eine Technik funktioniert am besten bei großen Textsammlungen (in
der Tat wurde sie sorgfältig darauf optimiert). Bei sehr kleinen Tabellen
spiegelt die Wortverteilung nicht adäquat seinen semantischen Wert wider,
so dass dieses Modell manchmal bizarre Ergebnisse ergeben kann:

@example
mysql> SELECT * FROM artikel WHERE MATCH (titel,artikeltext) AGAINST ('MySQL');
Empty set (0.00 sec)
@end example

Die Suche nach dem Wort @code{MySQL} erzeugt im obigen Beispiel keine
Ergebnisse. Das Wort @code{MySQL} ist in mehr als der Hälfte der Zeilen
vorhanden und wird deshalb als Stopword betrachtet (eins mit dem
semantischen Wert 0). Das ist in der Tat das gewünschte Verhalten - eine
natürlichsprachige Anfrage sollte bei einer 1 GB großen Tabelle nicht jede
zweite Zeile zurückgeben.

Bei einem Wort, dass in der Hälfte der Zeilen in einer Tabelle
übereinstimmt, ist es nicht sehr wahrscheinlich, dass relevante Dokumente
gefunden werden, sondern statt dessen viele irrelevante Dokumente. Das
kennen wir alle aus Recherchen über Suchmaschinen auf dem Internet. Das ist
die Überlegung, die dahinter steht, dass solchen Wörtern ein niedriger
semantischer Wert @strong{in diesem bestimmten Satz von Daten} gegeben
wird.



@menu
* Fulltext Restrictions::       
* Fulltext Fine-tuning::        
* Volltext-Features in MySQL 4.0::  
* Fulltext TODO::               
@end menu

@node Fulltext Restrictions, Fulltext Fine-tuning, Fulltext Search, Fulltext Search
@c German node Volltext-Einschränkungen
@subsection Volltext-Einschränkungen

@itemize @bullet
@item
Alle Parameter der @code{MATCH}-Funktion müssen Spalten derselben Tabelle
sein, die Teil desselben Volltext-Indexes ist.
@item
Das Argument für @code{AGAINST} muss eine Konstanten-Zeichenkette sein.
@end itemize


@node Fulltext Fine-tuning, Volltext-Features in MySQL 4.0, Fulltext Restrictions, Fulltext Search
@c German node Volltext-Feineinstellungen
@subsection MySQL-Volltextsuche fein einstellen

@c German FIX changed @xref to @pxref
Leider hat die Volltextsuche noch keine durch den Benutzer einstellbare
Parameter, doch diese stehen sehr weit oben auf der TODO-Liste. Wenn Sie
jedoch eine MySQL-Quelldistribution
(@pxref{Installing source})
haben, können Sie das Verhalten der Volltextsuche in einiger Hinsicht
ändern.

Beachten Sie, dass die Volltextsuche sorgfältig auf beste Sucheffektivität
eingestellt wurde. Wenn Sie dieses vorgabemäßige Verhalten ändern, wird
das die Suchergebnisse in den meisten Fällen verschlechtern. Ändern Sie die
MySQL-Quelltexte deshalb nur, wenn Sie genau wissen, was Sie tun!

@itemize @bullet

@item
Die minimale zu indexierende Wortlänge wird in der
@code{myisam/ftdefs.h}-Datei in folgender Zeile festgelegt:
@example
#define MIN_WORD_LEN 4
@end example
Ändern Sie diesen Wert nach Belieben, kompilieren Sie MySQL neu und bauen
Sie Ihre @code{FULLTEXT}-Indexe neu auf.

@item
Die Stopword-Liste wird in @code{myisam/ft_static.c} definiert. Ändern Sie
sie nach Ihrem Geschmack, kompilieren Sie MySQL neu und bauen Sie Ihre
@code{FULLTEXT}-Indexe neu auf.

@item
Die 50%-Schwelle wird durch das spezielle, ausgewählte Gewichtungsschema
festgelegt. Um dieses abzuschalten, ändern Sie folgende Zeile in
@code{myisam/ftdefs.h}:
@example
#define GWS_IN_USE GWS_PROB
@end example
zu
@example
#define GWS_IN_USE GWS_FREQ
@end example
und kompilieren Sie MySQL neu.
In diesem Fall brauchen Sie die Indexe nicht neu aufzubauen.

@end itemize


@node Volltext-Features in MySQL 4.0, Fulltext TODO, Fulltext Fine-tuning, Fulltext Search
@c German node <no English equivalent>
@subsection Neue Features der Volltextsuche in MySQL 4.0

Dieser Abschnitt enthält eine Auflistung der Volltext-Features, die bereits
im MySQL-4.0-Baum implementiert sind. Er erläutert den @strong{More
Funktionen für Volltextsuche}-Eintrag in @ref{TODO}.

@itemize @bullet
@item @code{REPAIR TABLE} mit @code{FULLTEXT}-Indexen, @code{ALTER TABLE}
mit @code{FULLTEXT}-Indexen und @code{OPTIMIZE TABLE} mit
@code{FULLTEXT}-Indexen läuft jetzt bis zu 100 mal schneller.

@item @code{MATCH ... AGAINST} wird folgende @strong{Boolesch Operatoren}
unterstützen:

@itemize @bullet
@item @code{+}wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile
enthalten sein @strong{muss}.
@item @code{-}wort bedeutet, dass das Wort in jeder zurückgegebenen Zeile
@strong{nicht} enthalten sein darf.
@item @code{<} und @code{>} können benutzt werden, um die Wortgewichtung in
der Anfrage herab- und heraufzusetzen.
@item @code{~} kann benutzt werden, um einem 'Rausch-Wort' ein
@strong{negatives} Gewicht zuzuweisen.
@item @code{*} ist ein Trunkierungsoperator.
@end itemize

Die Boole'sche Suche benutzt eine vereinfachte Art, die Relevanz zu
berechnen, die keine 50%-Schwelle hat.

@item Suchen sind jetzt wegen optimierter Suchalgorithmen bis zu 2 mal
schneller.

@item Das Dienstprogramm @code{ft_dump} wurde für
Low-Level-@code{FULLTEXT}-Index-Operationen hinzugefügt (Anfragen / Dumps /
Statistiken).

@end itemize


@node Fulltext TODO,  , Volltext-Features in MySQL 4.0, Fulltext Search
@c German node Volltext-TODO-Liste
@subsection Volltextsuche TODO-Liste

@itemize @bullet
@item Alle Operationen mit @code{FULLTEXT}-Index @strong{schneller} machen.
@item Unterstützung für Klammern @code{()} in Boole'scher Volltextsuche.
@item Phrasensuche, Näherungsoperatoren
@item Boole'sche Suche funktioniert ohne @code{FULLTEXT}-Index (ja,
@strong{sehr} langsam).
@item Unterstützung für "immer indizierte Wörter". Das könnten beliebige
Zeichenketten sein, die der Benutzer wie Wörter behandeln will. Beispiele
sind "C++", "AS/400", "TCP/IP" usw.
@item Unterstützung für Volltextsuche in @code{MERGE}-Tabellen.
@item Unterstützung für Multi-Byte-Zeichensätze.
@item Die Stopword-Liste von der Sprache der Daten abhängig machen.
@item Eindämmen (Stemming, natürlich abhängig von der Sprache der Daten).
@item Generischer Benutzer-unterstützbarer UDF- (?) Preparser.
@item Das Modell flexibler machen (durch Hinzufügen einiger regulierbarer
Parameter für @code{FULLTEXT} in @code{CREATE/ALTER TABLE}).
@end itemize


@c ACHTUNG! Folgender NODE ist neu seit 2002-01-15!
@c ATTENTION! The following node ist new since 2001-01-15!

@node Query Cache,  , Fulltext Search, Reference
@c German node Anfragen-Cache
@section MySQL-Anfragen-Cache

@cindex Anfragen-Cache
@cindex @code{SELECT}, Anfragen-Cache

Ab Version 4.0.1 besitzt der @code{MySQL-Server} einen
@code{Anfragen-Cache}. Wenn er benutzt wird, speichert er den Text einer
@code{SELECT}-Anfrage zusammen mit dem entsprechenden Ergebnis, das an den
Client gesendet wird. Wenn eine weitere identische Anfrage empfangen wird,
kann der Server die Ergebnisse aus dem Cache beziehen, statt dieselbe
Anfrage zu parsen und noch einmal auszuführen.

Der Anfragen-Cache ist extrem nützlich in Umgebungen, in denen sich
(einige) Tabellen nicht häufig ändern und in denen Sie viele identische
Anfragen haben. Das ist eine typische Situation für viele Web-Server, die
viele dynamische Inhalte benutzen.

Im folgenden finden Sie einige Performance-Daten für den Anfragen-Cache
(die wir mit der MySQL-Benchmark-Suite auf einer Linux Alpha 2 x 500 MHz
mit 2 GB RAM und einem 64-MB-Anfragen-Cache gewonnen haben):

@itemize @bullet
@item
Wenn Sie den Anfragen-Cache-Code abschalten wollen, setzen Sie
@code{query_cache_size=0}. Wenn Sie den Anfragen-Cache-Code abschalten,
gibt es keinen bemerkbaren Overhead.
@item
Wenn alle Anfragen, die Sie ausführen, einfach sind (wie das Auswählen
einer Zeile aus einer Tabelle mit einer Zeile), sich aber dennoch
unterscheiden, so dass die Anfragen nicht gecachet werden können, ist der
Overhead bei einem aktiven Anfragen-Cache 13%. Das sollte als Szenario für
den schlechtesten Fall angesehen werden. Im echten Leben sind Anfragen
jedoch meist viel komplizierter, so dass der Overhead normalerweise
beträchtlich geringer ist.
@item
Die Suche nach einer Zeile in einer Einzeilen-Tabelle ist 238% schneller.
Das kann als minimale Geschwindigkeitssteigerung für eine gecachete Anfrage
betrachtet werden.
@end itemize



@menu
* Query Cache How::             
* Query Cache Configuration::   
* Query Cache in SELECT::       
* Query Cache Status and Maintenance::  
@end menu

@node Query Cache How, Query Cache Configuration, Query Cache, Query Cache
@c German node Anfragen-Cache-Funktionsweise
@subsection Wie der Anfragen-Cache funktioniert

Anfragen werden vor dem Parsen verglichen, daher werden

@example
SELECT * FROM TABELLE
@end example

und

@example
Select * from tabelle
@end example

als unterschiedliche Anfragen für den Anfragen-Cache betrachtet. Anfragen
müssen also exakt gleich sein (Byte für Byte), um als identisch erkannt zu
werden. Zusätzlich kann eine Anfrage als unterschiedlich betrachtet werden,
wenn ein Client zum Beispiel ein neues Kommunikationsprotokollformat
benutzt oder einen anderen Zeichensatz als ein anderer Client.

Anfragen, die unterschiedliche Datenbanken, Protokollversionen oder
unterschiedliche vorgabemäßige Zeichensätze benutzen, werden als
unterschiedliche Anfragen angesehen und separat gecachet.

Der Cache funktioniert auch bei Anfragen der Art @code{SELECT CALC_ROWS
...} und @code{SELECT FOUND_ROWS() ...}, weil die Anzahl der gefundenen
Zeilen ebenfalls im Cache gespeichert wird.

Wenn sich eine Tabelle ändert (@code{INSERT}, @code{UPDATE}, @code{DELETE},
@code{TRUNCATE}, @code{ALTER} oder @code{DROP TABLE|DATABASE}), werden alle
gecacheten Anfragen, die diese Tabelle benutzten (möglicherweise über eine
@code{MRG_MyISAM}-Tabelle!) ungültig und werden aus dem Cache entfernt.

Momentan werden alle @code{InnoDB}-Tabellen beim @code{COMMIT} als für den
Cache ungültig gekennzeichnet. In Zukunft wird das geändert, so dass nur
Tabellen, die in der Transaktion geändert wurden, für die entsprechenden
Cache-Einträge als ungültig markiert werden.

Eine Anfrage kann nicht gecachet werden, wenn sie eine der folgenden
Funktionen enthält:
@multitable @columnfractions .25 .25 .25 .25
@item @strong{Funktion} @tab @strong{Funktion}
 @tab @strong{Funktion} @tab @strong{Funktion}
@item @code{Benutzerdefinierte Funktionen} @tab @code{CONNECTION_ID}
 @tab @code{FOUND_ROWS} @tab @code{GET_LOCK}
@item @code{RELEASE_LOCK} @tab @code{LOAD_FILE}
 @tab @code{MASTER_POS_WAIT} @tab @code{NOW}
@item @code{SYSDATE} @tab @code{CURRENT_TIMESTAMP}
 @tab @code{CURDATE} @tab @code{CURRENT_DATE}
@item @code{CURTIME} @tab @code{CURRENT_TIME}
 @tab @code{DATABASE} @tab @code{ENCRYPT} (mit einem Parameter)
@item @code{LAST_INSERT_ID} @tab @code{RAND}
 @tab @code{UNIX_TIMESTAMP} (ohne Parameter) @tab @code{USER}
@item @code{BENCHMARK}
@end multitable

Eine Anfrage kann ebenfalls nicht gecachet werden, wenn sie
Benutzer-Variablen enthält oder wenn sie in der Form @code{SELECT ... IN
SHARE MODE} oder der Form @code{SELECT * FROM AUTOINCREMENT_FIELD IS NULL}
(um als ODBC-Workaround die letzte eingefügte ID abzurufen) ist.

@code{FOUND ROWS()} gibt jedoch den korrekten Werte zurück, selbst wenn
eine vorhergehende Anfrage aus dem Cache geholt wurde.

Anfragen, die keinerlei Tabellen benutzen oder solche, bei denen der
Benutzer eine Spaltenberechtigung für irgend eine der beteiligten Tabellen
hat, werden nicht gecachet.

Bevor eine Anfrage aus dem Anfragen-Cache geholt wird, prüft MySQL, ob der
Benutzer die SELECT-Berechtigung für alle beteiligten Datenbanken und
Tabellen hat. Wenn nicht, wird das Cache-Ergebnis nicht benutzt.

@node Query Cache Configuration, Query Cache in SELECT, Query Cache How, Query Cache
@c German node Anfragen-Cache-Konfiguration
@subsection Anfragen-Cache-Konfiguration

Aufgrund des Anfragen-Caches gibt es ein paar neue @code{MySQL}
Systemvariablen für @code{mysqld}, die in einer Konfigurationsdatei oder
auf der Kommandozeile beim Starten von @code{mysqld} gesetzt werden können:

@itemize
@item @code{query_cache_limit}
Keine Ergebnisse cachen, die größer als dieser Wert sind (Vorgabe 1 MB).

@item @code{query_cache_size}
Der zugewiesene Arbeitsspeicher, um Ergebnisse aus alten Anfragen zu
speichern. Wenn er 0 ist, ist der Anfragen-Cache abgeschaltet (Vorgabe).

@item @code{query_cache_startup_type}
Dieser Wert (nur Zahlen) kann wie folgt gesetzt werden:
@multitable @columnfractions .3 .7
@item @strong{Option} @tab @strong{Beschreibung}
@item 0 @tab (OFF - AUS, Ergebnisse nicht cachen oder abrufen)
@item 1 @tab (ON - AN, alle Ergebnisse ausser @code{SELECT SQL_NO_CACHE ...}-Anfragen cachen)
@item 2 @tab (DEMAND - AUF VERLANGEN, nur @code{SELECT SQL_CACHE ...}-Anfragen cachen)
@end multitable
@end itemize


Innerhalb eines Threads (Verbindung) kann das Verhalten des Anfragen-Caches
abweichend von der Vorgabe verändert werden. Die Syntax ist wie folgt:

@code{SQL_QUERY_CACHE_TYPE = OFF | ON | DEMAND}
@code{SQL_QUERY_CACHE_TYPE = 0   | 1  | 2}

@multitable @columnfractions .3 .7
@item @strong{Option} @tab @strong{Beschreibung}
@item 0 oder OFF @tab Keine Ergebnisse cachen oder abrufen.
@item 1 oder ON @tab Alle Ergebnisse ausser @code{SELECT SQL_NO_CACHE ...}-Anfragen cachen.
@item 2 oder DEMAND @tab Nur @code{SELECT SQL_CACHE ...}-Anfragen cachen.
@end multitable

Vorgabemäßig hängt @code{SQL_QUERY_CACHE_TYPE} vom Wert von
@code{query_cache_startup_type} ab, als der Thread erzeugt wurde.


@node Query Cache in SELECT, Query Cache Status and Maintenance, Query Cache Configuration, Query Cache
@c German node Anfragen-Cache in SELECT
@subsection Anfragen-Cache-Optionen in @code{SELECT}

Es gibt zwei mögliche Anfragen-Cache-bezogene Parameter, die in einer
@code{SELECT}-Anfrage angegeben werden können:

@findex SQL_CACHE
@findex SQL_NO_CACHE

@multitable @columnfractions .3 .7
@item @strong{Option} @tab @strong{Beschreibung}
@item @code{SQL_CACHE}
 @tab Wenn @code{SQL_QUERY_CACHE_TYPE} @code{DEMAND} ist, darf die Anfrage gecachet werden.
 Wenn @code{SQL_QUERY_CACHE_TYPE} @code{ON} ist, ist das die Vorgabe.
 Wenn @code{SQL_QUERY_CACHE_TYPE} @code{OFF} ist, nichts tun.
@item @code{SQL_NO_CACHE}
 @tab Diese Anfrage wird nicht gecachet.
@end multitable


@node Query Cache Status and Maintenance,  , Query Cache in SELECT, Query Cache
@c German node Anfragen-Cache-Status und -Wartung
@subsection Anfragen-Cache-Status und -Wartung

Mit dem @code{FLUSH QUERY CACHE}-Befehl können Sie den Anfragen-Cache
defragmentieren, um den Speicher besser zu benutzen. Dieser Befehl entfernt
keinerlei Anfragen aus dem Cache.
@code{FLUSH TABLES} schreibt auch den Anfragen-Cache zurück auf Platte.

Der @code{RESET QUERY CACHE}-Befehl entfernt alle Anfragenergebnisse aus
dem Anfragen-Cache.

Sie können die Anfragen-Cache-Performance in @code{SHOW STATUS} beobachten:

@multitable @columnfractions .3 .7
@item @strong{Variable} @tab @strong{Beschreibung}
@item @code{Qcache_queries_in_cache}
 @tab Anzahl von Anfragen, die im Cache registriert sind.
@item @code{Qcache_inserts}
 @tab Anzahl von Anfragen, die zum Cache hinzugefügt wurden.
@item @code{Qcache_hits}
 @tab Anzahl von Cache-Hits.
@item @code{Qcache_not_cached}
 @tab Anzahl von nicht gecacheten Anfragen
 (nicht cachebar oder wegen @code{SQL_QUERY_CACHE_TYPE}).
@item @code{Qcache_free_memory}
 @tab Menge des freien Speichers für den Anfragen-Cache.
@item @code{Qcache_total_blocks}
 @tab Gesamtzahl von Blöcken im Anfragen-Cache.
@item @code{Qcache_free_blocks}
 @tab Anzahl freier Speicherblöcke im Anfragen-Cache.
@end multitable

Gesamtzahl von Anfragen =
@code{Qcache_inserts} + @code{Qcache_hits} + @code{Qcache_not_cached}.

Der Anfragen-Cache benutzt variable Blocklängen, so dass
@code{Qcache_total_blocks} und @code{Qcache_free_blocks} eine
Speicherfragmentierung des Anfragen-Caches anzeigen können. Nach
@code{FLUSH QUERY CACHE} verbleibt nur ein einzelner (großer) freier
Block.

Hinweis: Jede Anfrage benötigt minimal zwei Blöcke (einen für den
Anfragentext und einen weiteren für das Anfragenergebnis). Ausserdem
benötigt jede Tabelle, die in einer Anfrage benutzt wurde, einen Block.
Wenn allerdings zwei oder mehr Anfragen dieselbe Tabelle benutzen, muss nur
ein Block zugewiesen werden.


@c ACHTUNG! Folgender NODE ist geändert, 2002-01-15!
@c ATTENTION! The following node has been changed 2001-01-15!
@node Table types, Clients, Reference, Top
@c German node Tabellentypen
@chapter MySQL-Tabellentypen

@cindex Tabellentypen, Auswahl
@cindex @code{InnoDB}-Tabellentyp
@cindex @code{Berkeley_db}-Tabellentyp
@cindex @code{HEAP}-Tabellentyp
@cindex @code{ISAM}-Tabellentyp
@cindex @code{BDB}-Tabellentyp
@cindex @code{MERGE}-Tabellentyp
@cindex MySQL-Tabellentypen
@cindex @code{MyISAM}-Tabellentyp
@cindex Typen, Tabellen-

AB MySQL-Version 3.23.6 können Sie unter drei grundlegenden
Tabellenformaten (@code{ISAM}, @code{HEAP} und @code{MyISAM} wählen. Neuere
MySQL-Versionen können zusätzliche Tabellentypen unterstützen
(@code{InnoDB}, oder @code{BDB}), abhängig davon, wie Sie sie kompilieren.
 

Beim Erzeugen einer neuen Tabelle können Sie MySQL mitteilen, welcher
Tabellentyp dafür benutzt werden soll. MySQL erzeugt immer eine
@code{.frm}-Datei, die die Tabellen- und Spaltendefinitionen enthält.
Abhängig vom Tabellentyp werden Index und Daten in anderen Dateien
gespeichert.

Beachten Sie, dass Sie für die Benutzung von @code{InnoDB}-Tabellen
zumindest die @code{innodb_data_file_path}-Startoption benötigen.
@xref{InnoDB start}.

Der vorgabemäßige Tabellentyp in MySQL ist @code{MyISAM}. Wenn Sie
versuchen, einen Tabellentyp zu benutzen, der nicht einkompiliert oder
aktiviert ist, erzeugt MySQL statt dessen eine Tabelle vom Typ
@code{MyISAM}. Das ist ein sehr nützliches Feature, wenn Sie Tabellen
zwischen unterschiedlichen SQL-Servern kopieren wollen, die
unterschiedliche Tabellentypen unterstützten (zum Beispiel Tabellen zu
einem Slave kopieren, der für Geschwindigkeit optimiert ist, aber keine
transaktionalen Tabellen hat). Dieses automatische Ändern des Tabellentyps
kann andererseits für neue MySQL-Benutzer sehr verwirrend sein. Wir planen
für MySQL 4.0, das zu beheben, indem eine Warnung ausgegeben wird, wenn ein
Tabellentyp automatisch geändert wird.

Sie können Tabellen zwischen unterschiedlichen Typen mit dem @code{ALTER
TABLE}-Statement umwandeln. @xref{ALTER TABLE, , @code{ALTER TABLE}}.

MySQL unterstützt zwei unterschiedliche Arten von Tabellen:
transaktionssichere Tabellen (@code{InnoDB} und @code{BDB}) und nicht
transaktionssichere Tabellen (@code{HEAP}, @code{ISAM}, @code{MERGE} und
@code{MyISAM}).

Vorteile transaktionssicherer Tabellen (TST):

@itemize @bullet
@item
Sicherer. Selbst wenn MySQL abstürzt oder wenn Sie Hardware-Probleme
bekommen, bekommen Sie Ihre Daten zurück, entweder über automatische
Wiederherstellung oder von einer Datensicherung plus Transaktionslog-Datei.
@item
Sie können viele Statements kombinieren und alle in einem Rutsch mit dem
@code{COMMIT}-Befehl akzeptieren.
@item
Sie können @code{ROLLBACK} ausführen, um Ihre Änderungen zu ignorieren
(wenn Sie nicht im Auto-Commit-Modus fahren).
@item
Wenn eine Aktualisierung fehlschlägt, werden Ihre Änderungen
zurückgesichert. (Bei nicht transaktionssicheren Tabellen sind
durchgeführte Änderungen permanent.)
@end itemize

Vorteile nicht transaktionssicherer Tabellen (NTST):

@itemize @bullet
@item
Viel schneller, da es keinen Transaktionsoverhead gibt.
@item
Benötigen aufgrund des fehlenden Transaktionsoverheads weniger
Speicherplatz.
@item
Benötigen weniger Arbeitsspeicher für Aktualisierungen.
@end itemize

Sie können TST- and NTST-Tabellen in denselben Statements kombinieren, um
das Beste aus beiden Welten zu bekommen.



@menu
* MyISAM::                      
* MERGE::                       
* ISAM::                        
* HEAP::                        
* InnoDB::                      
* BDB::                         
@end menu

@node MyISAM, MERGE, Table types, Table types
@c German node MyISAM
@section MyISAM-Tabellen

@code{MyISAM} ist der vorgabemäßige Tabellentyp in MySQL-Version 3.23. Er
basiert auf dem @code{ISAM}-Code und hat viele nützliche Erweiterungen.

Der Index wird in einer Datei mit der Endung @code{.MYI} (MYIndex)
gespeichert, die Daten in einer Datei mit der Endung @code{.MYD} (MYData).
Sie können @code{MyISAM}-Tabellen mit dem @code{myisamchk}-Dienstprogramm
überprüfen und reparieren. @xref{Repair}. Sie können
@code{MyISAM}-Tabellen mit @code{myisampack} komprimieren, damit sie viel
weniger Speicherplatz benötigen. @xref{myisampack}.

Folgende Neuerungen gibt es bei @code{MyISAM}:

@itemize @bullet
@item
Es gibt einen Flag in der @code{MyISAM}-Datei, der anzeigt, ob die Tabelle
korrekt geschlossen wurde. Wenn @code{mysqld} mit @code{--myisam-recover}
gestartet wird, werden @code{MyISAM}-Tabellen beim Öffnen automatisch
geprüft und / oder repariert, falls die Tabelle nicht korrekt geschlossen
wurde.
@item
Sie können neue Zeilen in eine Tabelle, die keinerlei freie Blöcke mitten
in der Daten-Datei hat, einfügen (@code{INSERT}), während zeitgleich
andere Threads aus der Tabelle lesen (zeitgleiches Einfügen). Ein freier
Block kann entstehen, wenn eine Aktualisierung einer Zeile dynamischer
Länge, die viele Daten enthält, mit weniger Daten durchgeführt wird, oder
wenn Zeilen gelöscht werden. Wenn alle freien Blöcke aufgebraucht sind,
können alle zukünftigen Einfügeoperationen auf die zeitgleiche Art
erfolgen.
@item
Unterstützung für große Dateien (63-Bit) auf Dateisystemen /
Betriebssystemen, die große Dateien unterstützen.
@item
Alle Daten werden mit dem niedrigen Byte zuerst gespeichert. Das macht die
Daten Maschinen- und Betriebssystem-unabhängig. Die einzige Anforderung
ist, dass die Maschine zweien-komplementäre vorzeichenbehaftete Ganzzahlen
(two's-complement signed integers) benutzt, was bei jeder Maschine in den
letzten 20 Jahren der Fall war), sowie das IEEE-Fließkomma-Format (bei
Mainstream-Maschinen absolut dominierend). Die einzige Art von Maschinen,
die vielleicht keine Binärkompatibilität unterstützen, sind eingebettete
Systeme (Embedded Systems), weil diese manchmal eigentümliche Prozessoren
haben.

Wenn Daten mit dem niedrigen Byte zuerst gespeichert werden, ergibt sich
daraus kein großer Geschwindigkeitsnachteil. Die Bytes in einer
Tabellenzeile sind normalerweise unzusammenhängend und man benötigt kaum
mehr Ressourcen, um ein unzusammenhängendes Byte in Reihenfolge statt in
umgekehrter Reihenfolge zu lesen. Der tatsächliche Hole-Spaltenwert-Code
ist im Vergleich zu sonstigem Code ebenfalls nicht zeitkritisch.
@item
Alle Zahlenschlüssel werden mit dem hohen Byte zuerst gespeichert, um
bessere Index-Kompression zu erzielen.
@item
Die interne Handhabung einer @code{AUTO_INCREMENT}-Spalte. @code{MyISAM}
aktualisiert diese automatisch bei @code{INSERT / UPDATE}. Der
@code{AUTO_INCREMENT}-Wert kann mit @code{myisamchk} zurückgesetzt werden.
Das macht @code{AUTO_INCREMENT}-Spalten schneller (mindestens 10%), und
alten Zahlen werden im Gegensatz zum alten @code{ISAM} nicht wieder
benutzt. Beachten Sie, dass das alte Verhalten immer noch da ist, wenn ein
@code{AUTO_INCREMENT} am Ende eines mehrteiligen Schlüssels definiert wird.
@item
Wenn er in sortierter Reihenfolge eingefügt wird (wie bei der Benutzung
einer @code{AUTO_INCREMENT}-Spalte), wird der Schlüsselbaum gespalten, so
dass der hohe Knoten nur einen Schlüssel enthält. Das verbessert die
Platzausnutzung im Schlüsselbaum.
@item
@code{BLOB}- und @code{TEXT}-Spalten können indiziert werden.
@item
@code{NULL}-Werte sind in indizierten Spalten erlaubt. Dafür werden 0 bis 1
Byte pro Schlüssel benötigt.
@item
Die maximale Schlüssellänge beträgt vorgabemäßig 500 Bytes (das kann beim
Neukompilieren geändert werden). Wenn Schlüssel länger als 250 Bytes sind,
wird für diese eine höhere Schlüsselblockgröße als die vorgabemäßigen
1024 Bytes benutzt.
@item
Die maximale Anzahl von Schlüsseln pro Tabelle beträgt vorgabemäßig 32.
Diese kann bis auf 64 erhöht werden, ohne dass @code{myisamchk} neu
kompiliert werden muss.
@item
@code{myisamchk} kennzeichnet Tabellen als geprüft, wenn es mit
@code{--update-state} läuft. @code{myisamchk --fast} prüft nur die
Tabellen, die diese Kennzeichnung nicht haben.
@item
@code{myisamchk -a} speichert Statistiken für Schlüsselteile (und nicht nur
für gesamte Schlüssel wie bei @code{ISAM}).
@item
Zeilen dynamischer Größe werden viel weniger fragmentiert werden, wenn
Lösch- mit Aktualisierungs- und Einfügeoperationen gemischt werden. Dafür
wird gesorgt, indem angrenzende gelöschte Blöcke automatisch kombiniert
werden und dadurch, dass Blöcke erweitert werden, wenn der nächste Block
gelöscht wird.
@item
@code{myisampack} kann @code{BLOB}- and @code{VARCHAR}-Spalten
komprimieren.
@item
Sie können die Daten-Datei und die Index-Datei in unterschiedliche
Verzeichnisse legen, um mehr Geschwindigkeit zu erhalten (mit der
@code{DATA/INDEX DIRECTORY="pfad"}-Option für @code{CREATE TABLE}).
@xref{CREATE TABLE}.
@end itemize

@code{MyISAM} unterstützt ausserdem die folgenden Dinge, die MySQL in naher
Zukunft benutzen können wird:

@itemize @bullet
@item
Unterstützung für einen echten @code{VARCHAR}-Typ. Eine
@code{VARCHAR}-Spalte fängt mit einer in 2 Bytes gespeicherten Länge an.
@item
Tabellen mit @code{VARCHAR} können eine feste oder dynamische
Datensatzlänge haben.
@item
@code{VARCHAR} und @code{CHAR} können bis zu 64 KB Groß sein. Alle
Schlüsselsegmente haben ihre eigene Sprachdefinition. Das versetzt MySQL in
die Lage, unterschiedliche Sprachdefinitionen pro Spalte zu haben.
@item
Ein gehashter berechneter Index kann für @code{UNIQUE} benutzt werden. Das
erlaubt Ihnen, @code{UNIQUE} auf jeder beliebigen Kombination von Spalten
in einer Tabelle zu haben. (Sie können jedoch auf einem @code{UNIQUE}
berechneten Index nicht suchen.)
@end itemize

Beachten Sie, dass Index-Dateien bei @code{MyISAM} üblicherweise viel
kleiner sind als bei @code{ISAM}. Das bedeutet, dass @code{MyISAM}
normalerweise weniger Systemressourcen verbraucht als @code{ISAM},
allerdings mehr Prozessorleistung beim Einfügen von Daten in einen
komprimierten Index.

Folgende Optionen für @code{mysqld} können benutzt werden, um das Verhalten
von @code{MyISAM}-Tabellen zu ändern. @xref{SHOW VARIABLES}.

@multitable @columnfractions .40 .60
@item @strong{Option} @tab @strong{Beschreibung}
@item @code{--myisam-recover=#}
 @tab Automatische Wiederherstellung beschädigter Tabellen.
@item @code{-O myisam_sort_buffer_size=#}
 @tab Der beim Wiederherstellen von Tabellen benutzte Puffer.
@item @code{--delay-key-write-for-all-tables}
 @tab Keine Schlüsselpuffer zwischen Schreibvorgängen auf jedwede
MyISAM-Tabelle zurückschreiben (flush).
@item @code{-O myisam_max_extra_sort_file_size=#}
 @tab Wird benutzt, um MySQL bei der Entscheidung zu helfen, wann die
langsame, aber sichere Schlüssel-Cache-Index-Erzeugungsmethode benutzt
werden sollte. @strong{Hinweis:} Dieser Parameter wird in Megabytes
angegeben!
@item @code{-O myisam_max_sort_file_size=#}
 @tab Die schnelle Index-Sortiermethode beim Erzeugen eines Indexes nicht
benutzen, wenn die temporäre Datei größer als dieser Wert werden würde.
@strong{Hinweis:} Dieser Parameter wird in Megabytes angegeben!
megabytes!--
@item @code{-O myisam_bulk_insert_tree_size=#}
 @tab Die Größe des Baum-Caches, der bei der Optimierung von
Massen-Einfügeoperationen benutzt wird. @strong{Hinweis:} Das ist die
Begrenzung @strong{pro Thread}!
@end multitable

Die automatische Wiederherstellung wird aktiviert, wenn Sie @code{mysqld}
mit @code{--myisam-recover=#} starten. @xref{Command-line options}. Beim
Öffnen wird geprüft, ob die Tabelle als beschädigt gekennzeichnet ist oder
ob die Zählvariable für die Tabelle nicht 0 ist und Sie mit
@code{--skip-locking} laufen lassen. Wenn eine dieser Bedingungen erfüllt
ist, geschieht folgendes:

@itemize @bullet
@item
Die Tabelle wird auf Fehler geprüft.
@item
Wenn ein Fehler gefunden wird, wird eine schnelle Reparatur der Tabelle
versucht (mit Sortieren und ohne Neuerzeugung der Daten-Datei).
@item
Wenn die Reparatur wegen eines Fehlers in der Daten-Datei fehlschlägt (zum
Beispiel ein Fehler wegen eines doppelten Schlüsseleintrags), wird die
Reparatur noch einmal versucht, diesmal allerdings mit Neuerzeugung der
Daten-Datei.
@item
Wenn dieser Versuch fehlschlägt, wird die Reparatur noch einmal mit der
alten Reparaturoption versucht (Zeile für Zeile ohne Sortieren schreiben),
was jede Sorte von Fehler beheben sollte, bei gewissen
Festplatten-Erfordernissen ...
@end itemize

Wenn die Wiederherstellung nicht in der Lage ist, alle Zeilen aus einem
vorher abgeschlossenen Statement wiederherzustellen, und Sie nicht
@code{FORCE} als Option für @code{myisam-recover} angegeben haben, wird die
automatische Reparatur mit einer Fehlermeldung in der Fehlerdatei
abgebrochen:

@example
Error: Couldn't repair table: test.g00pages
@end example

Hätten Sie in diesem Fall die @code{FORCE}-Option benutzt, würden Sie statt
dessen in der Fehlerdatei eine Warnung erhalten:

@example
Warning: Found 344 of 354 rows when repairing ./test/g00pages
@end example

Wenn Sie automatisches Wiederherstellung mit der @code{BACKUP}-Option
laufen lassen, beachten Sie, dass Sie ein Cron-Skript haben sollten, dass
automatisch Dateien mit Namen wie @file{tabellenname-datetime.BAK} aus den
Datenbank-Verzeichnissen auf ein Sicherungsmedium verschiebt.

@xref{Command-line options}.



@menu
* Key space::                   
* MyISAM table formats::        
* MyISAM table problems::       
@end menu

@node Key space, MyISAM table formats, MyISAM, MyISAM
@c German node Speicherplatz für Schlüssel
@subsection Für Schlüssel benötigter Speicherplatz

@cindex Speicherplatz für Schlüssel, MyISAM

MySQL unterstützt unterschiedliche Index-Typen, doch der normale Typ ist
ISAM oder MyISAM. Diese benutzen einen B-Baum-Index, und Sie können die
Größe der Index-Datei grob als @code{(schluessel_laenge+4)/0.67}
kalkuliert, summiert über alle Schlüssel. (Das ist der schlechteste Fall,
bei dem alle Schlüssel in sortierter Reihenfolge eingeordnet werden und es
keinerlei Schlüssel-Komprimierung gibt.)

Zeichenketten-Indexe werden Leerzeichen-komprimiert. Wenn der erste
Index-Teil eine Zeichenkette ist, wird er zusätzlich Präfix-komprimiert.
Leerzeichen-Kompression macht die Index-Datei kleiner als in den obigen
Zahlen dargestellt, wenn die Zeichenkettenspalte viele Leerzeichen am Ende
hat oder eine @code{VARCHAR}-Spalte ist, die nicht immer in voller Länge
genutzt wird. Präfix-Kompression wird bei Schlüsseln benutzt, die mit einer
Zeichenkette beginnen. Präfix-Kompression hilft, wenn es viele
Zeichenketten mit identischem Präfix gibt.

Bei @code{MyISAM}-Tabellen können Sie auch Zahlen Präfix-komprimieren,
indem Sie beim Erzeugen der Tabelle @code{PACK_KEYS=1} angeben. Das hilft,
wenn Sie viele Ganzzahl-Schlüssel mit identischem Präfix haben, wenn die
Zahlen mit dem hohen Byte zuerst gespeichert werden.


@node MyISAM table formats, MyISAM table problems, Key space, MyISAM
@c German node MyISAM-Tabellenformate
@subsection MyISAM-Tabellenformate

@strong{MyISAM} unterstützt 3 verschiedene Tabellentypen. Zwei von ihnen
werden automatisch gewählt, abhängig vom Spaltentyp, den Sie benutzen. Der
dritte, komprimierte Tabellen, kann nur mit dem
@code{myisampack}-Dienstprogramm erzeugt werden.

Wenn Sie eine Tabelle erzeugen (@code{CREATE}) oder ändern (@code{ALTER}),
können Sie bei Tabellen, die kein @code{BLOB} enthalten, ein dynamisches
(@code{DYNAMIC}) oder festes (@code{FIXED}) Tabellenformat mit der
@code{ROW_FORMAT=#}-Tabellenoption erzwingen. Zukünftig werden Sie in der
Lage sein, Tabellen zu komprimieren / dekomprimieren, indem Sie
@code{ROW_FORMAT=compressed | default} für @code{ALTER TABLE} angeben.
@xref{CREATE TABLE}.



@menu
* Static format::               
* Dynamic format::              
* Compressed format::           
@end menu

@node Static format, Dynamic format, MyISAM table formats, MyISAM table formats
@c German node Statisches Format
@subsubsection Kennzeichen statischer (Festlängen-) Tabellen

Das ist das vorgabemäßige Format. Es wird benutzt, wenn die Tabelle keine
@code{VARCHAR}-, @code{BLOB}- oder @code{TEXT}-Spalten enthält.

Dieses Format ist das einfachste und sicherste Format. Es ist auch das
schnellste der Formate auf Platte. Die Geschwindigkeit ergibt sich aus der
einfachen Weise, wie Daten auf der Platte gefunden werden können. Wenn man
etwas mit einem Index und statischem Format nachschlägt, ist es sehr
einfach. Man multipliziert einfach die Zeilennummer mit der Zeilenlänge.

Wenn eine Tabelle gescannt wird, ist es ausserdem sehr einfach, mit jedem
Plattenzugriff eine konstante Anzahl von Datensätzen zu lesen.

Die Sicherheit zeigt sich, wenn Ihr Computer beim Schreiben in eine
MyISAM-Datei fester Länge abstürzt. In diesem Fall kann @code{myisamchk}
leicht herausfinden, wo jede Zeile anfängt und aufhört. Daher kann es
üblicherweise alle Datensätze mit Ausnahme desjenigen, in den nur teilweise
geschrieben wurde, wieder herstellen. Beachten Sie, dass in MySQL alle
Indexe in jedem Fall wiederhergestellt werden können:

@itemize @bullet
@item
Alle @code{CHAR}-, @code{NUMERIC}- und @code{DECIMAL}-Spalten werden mit
Leerzeichen auf die Spaltenbreite aufgefüllt.
@item
Sehr schnell.
@item
Leicht zu cachen.
@item
Nach einem Absturz leicht zu rekonstruieren, weil sich Datensätze an festen
Positionen befinden.
@item
müssen nicht (mit @code{myisamchk}) reorganisiert werden, es sei denn, eine
riesige Anzahl von Datensätzen wurde gelöscht und Sie wollen dem
Betriebssystem freien Speicherplatz zurückgeben.
@item
Benötigen normalerweise mehr Speicherplatz als dynamische Tabellen.
@end itemize


@node Dynamic format, Compressed format, Static format, MyISAM table formats
@c German node Dynamisches Format
@subsubsection Kennzeichen dynamischer Tabellen

@cindex Kennzeichen dynamischer Tabellen
@cindex Tabellen, dynamische

Dieses Format wird benutzt, wenn die Tabelle irgend welche @code{VARCHAR}-,
@code{BLOB}- oder @code{TEXT}-Spalten enthält, oder wenn die Tabelle mit
@code{ROW_FORMAT=dynamic} erzeugt wurde.

Dieses Format ist etwas komplexer, weil jede Zeile einen Header haben muss,
der aussagt, wie lang sie ist. Ein Datensatz kann ausserdem an mehr als
einem Speicherplatz enden, wenn er bei einer Aktualisierung verlängert
wird.

@cindex Tabellen, defragmentieren
Sie können @code{OPTIMIZE table} oder @code{myisamchk} benutzen, um eine
Tabelle zu defragmentieren. Wenn Sie statische Daten haben, auf die Sie oft
zugreifen oder die Sie in derselben Tabelle oft ändern, als @code{VARCHAR}-
oder @code{BLOB}-Spalten haben, ist es eine gute Idee, die dynamischen
Spalten in andere Tabellen zu verschieben, einfach um Fragmentierung zu
vermeiden:

@itemize @bullet
@item
Alle Zeichenketten-Spalten sind dynamisch (ausser denen mit einer Länge
kleiner 4).
@item
Jedem Datensatz ist eine Bitmap vorangestellt, die angibt, welche Spalten
bei Zeichenketten-Spalten leer (@code{''}) sind oder 0 bei numerischen
Spalten. (Das ist nicht dasselbe wie Spalten, die @code{NULL}-Werte
enthalten.) Wenn eine Zeichenketten-Spalte nach der Entfernung von
Leerzeichen am Ende eine Länge von 0 hat oder eine numerische Spalte einen
Wert von 0 hat, wird sie in der Bitmap markiert und nicht auf Platte
gespeichert. Nicht leere Zeichenketten werden als ein Längen-Byte plus dem
Zeichenketten-Inhalt gespeichert.
@item
Benötigen üblicherweise weniger Plattenplatz als Festlängen-Tabellen.
@item
Jeder Datensatz benutzt nur so viel Speicherplatz wie erforderlich. Wenn
ein Datensatz größer wird, wird er in so viele Teile wie erforderlich
aufgeteilt. Hierdurch wird Datensatzfragmentierung hervorgerufen.
@item
Wenn Sie eine Zeile mit Informationen aktualisieren, die die Zeilenlänge
überschreiten, wird die Zeile fragmentiert. In diesem Fall sollten Sie von
Zeit zu Zeit @code{myisamchk -r} laufen lassen, um bessere Performance zu
erzielen. Benutzen Sie @code{myisamchk -ei tabellen_name}, um einige
statistische Informationen zu erhalten.
@item
Sind nach einem Absturz nicht so einfach zu rekonstruieren, weil ein
Datensatz in viele Teile fragmentiert sein und ein Link (Fragment) fehlen
kann.
@item
Die erwartete Zeilenlänge bei Datensätzen dynamischer Länge ist:

@example
3
+ (anzahl_der_spalten + 7) / 8
+ (anzahl_der_zeichenketten_spalten)
+ komprimierte_groesse_numerischer_spalten
+ laenge_von_zeichenketten
+ (anzahl_von_NULL_spalten + 7) / 8
@end example

Für jeden Link kommen 6 Bytes hinzu. Ein dynamischer Datensatz wird immer
dann verknüpft (linked), wenn eine Aktualisierung eine Vergrößerung des
Datensatzes bewirkt. Jede neue Verknüpfung hat mindestens 20 Bytes, so dass
die nächste Vergrößerung wahrscheinlich in dieselbe Verknüpfung passt.
Wenn nicht, entsteht eine weitere Verknüpfung. Sie können mit
@code{myisamchk -ed} prüfen, wie viele Verknüpfungen es gibt. Alle
Verknüpfungen können mit @code{myisamchk -r} entfernt werden.
@end itemize


@node Compressed format,  , Dynamic format, MyISAM table formats
@c German node Komprimiertes Format
@subsubsection Kennzeichen komprimierter Tabellen

@cindex Tabellen, komprimiertes Format

Das ist ein Nur-Lese-Typ, der mit dem optionalen
@code{myisampack}-Dienstprogramm (@code{pack_isam} für
@code{ISAM}-Tabellen) erzeugt wird:

@itemize @bullet
@item
All MySQL-Distributionen, selbst diejenigen, die es vor der GPL-Version von
MySQL gab, können Tabellen lesen, die mit @code{myisampack} komprimiert
wurden.
@item
Komprimierte Tabellen benötigen viel weniger Speicherplatz. Das minimiert
Plattenzugriffe, was sehr nett ist, wenn Sie langsame Platten benutzen (wie
CD-ROMs).
@item
Jeder Datensatz wird separat komprimiert (sehr geringer Zugriffs-Overhead).
Der Header für einen Datensatz hat eine feste Länge (1 bis 3 Bytes),
abhängig vom größten Datensatz in der Tabelle. Jede Spalte wird
unterschiedlich komprimiert. Einige Kompressionstypen sind:
@itemize @minus
@item
Für jede Spalte gibt es üblicherweise eine unterschiedliche
Huffman-Tabelle.
@item
Komprimierung von Leerzeichen am Ende.
@item
Komprimierung von Leerzeichen am Anfang.
@item
Zahlen mit dem Wert @code{0} werden mit 1 Bit gespeichert.
@item
Wenn Werte in einer Ganzzahl-Spalte einen kleinen Wertebereich haben, wird
die Spalte mit dem kleinsten möglichen Typ gespeichert. Eine
@code{BIGINT}-Spalte (8 Bytes) kann beispielsweise als
@code{TINYINT}-Spalte (1 Byte) gespeichert werden, wenn sich alle Werte im
Bereich von @code{0} bis @code{255} befinden.
@item
Wenn eine Spalte nur einen kleinen Satz möglicher Werte besitzt, wird der
Spaltentyp zu @code{ENUM} umgewandelt.
@item
Eine Spalte kann auch eine Kombination der obigen Komprimierungen benutzen.
@end itemize
@item
Kann Datensätze fester oder dynamischer Länge handhaben, aber nicht
@code{BLOB}- oder @code{TEXT}-Spalten.
@item
Kann mit @code{myisamchk} dekomprimiert werden.
@end itemize


@node MyISAM table problems,  , MyISAM table formats, MyISAM
@c German node MyISAM-Tabellenprobleme
@subsection MyISAM-Tabellenprobleme

Das Dateiformat, das MySQL benutzt, um Daten zu speichern, wurde ausgiebig
getestet, aber es gibt immer Umstände, die dazu führen können, dass
Datenbanktabellen beschädigt werden.



@menu
* Corrupted MyISAM tables::     
* MyISAM table close::          
@end menu

@node Corrupted MyISAM tables, MyISAM table close, MyISAM table problems, MyISAM table problems
@c German node Beschädigte MyISAM-Tabellen
@subsubsection Beschädigte MyISAM-Tabellen

Obwohl das MyISAM-Tabellenformat sehr zuverlässig ist (alle Änderungen an
einer Tabelle werden geschrieben, bevor das SQL-Statement zurückkehrt),
können Sie dennoch beschädigte Tabellen bekommen, wenn eines der folgenden
Dinge passiert:

@itemize @bullet
@item
Der @code{mysqld}-Prozess wird mitten in einem Schreibvorgang gekillt.
@item
Unerwartetes Herunterfahren des Computers (wenn der Computer beispielsweise
abgeschaltet wird).
@item
Ein Hardware-Fehler.
@item
Sie benutzen ein externes Programm (wie myisamchk) auf einer benutzten
Tabelle.
@item
Ein Software-Bug im MySQL- oder MyISAM-Code.
@end itemize

Typische Symptome einer beschädigten Tabelle sind:

@itemize @bullet
@item
Sie erhalten den Fehler @code{Incorrect key file for table: '...'. Try to
repair it}, wenn Sie Daten aus der Tabelle auswählen.
@item
Anfragen finden keine Zeilen in der Tabelle oder geben unvollständige Daten
zurück.
@end itemize

Sie können mit dem Befehl @code{CHECK TABLE} prüfen, ob eine Tabelle in
Ordnung ist. @xref{CHECK TABLE}.

Sie können eine beschädigte Tabelle mit @code{REPAIR TABLE} reparieren.
@xref{REPAIR TABLE}. Wenn @code{mysqld} nicht läuft, können Sie eine
Tabelle auch mit dem @code{myisamchk}-Befehl reparieren.
@code{myisamchk-Syntax}.

Wenn Ihre Tabellen oft beschädigt werden, sollten Sie versuchen, den Grund
dafür herauszufinden! @xref{Crashing}. 

In diesem Fall ist es am wichtigsten zu wissen, ob die Tabelle durch einen
Absturz von @code{mysqld} beschädigt wurde (das können Sie leicht
feststellen, wenn es eine aktuelle Zeile @code{restarted mysqld} in der
mysqld-Fehlerdatei gibt). Wenn das nicht der Fall ist, sollten Sie
versuchen, daraus einen Testfall zu machen. @xref{Reproduceable test case}.


@node MyISAM table close,  , Corrupted MyISAM tables, MyISAM table problems
@c German node MyISAM-Tabellenschließen
@subsubsection Client benutzt Tabelle oder hat sie nicht korrekt geschlossen

Jede @code{MyISAM}-@code{.MYI}-Datei hat im Header einen Zähler, der
benutzt werden kann, um zu prüfen, ob die Tabelle korrekt geschlossen
wurde.

Wenn Sie folgende Warnmeldung von @code{CHECK TABLE} oder @code{myisamchk}
erhalten:

@example
# client is using or hasn't closed the table properly
@end example

heißt das, dass der Zähler nicht mehr synchron ist. Das bedeutet nicht,
dass die Tabelle beschädigt ist, aber Sie sollten zumindest eine
Überprüfung vornehmen, um sicherzustellen, dass die Tabelle in Ordnung ist.

Der Zähler funktioniert wie folgt:

@itemize @bullet
@item
Wenn die Tabelle das erste Mal in MySQL aktualisiert wird, wird der Zähler
im Header der Index-Dateien heraufgezählt.
@item
Der Zähler wird während weiterer Aktualisierungen nicht verändert.
@item
Wenn die letzte Instanz einer Tabelle geschlossen wird (wegen eines
@code{FLUSH} oder weil es nicht mehr genug Platz im Tabellen-Cache gibt),
wird der Zähler heruntergezählt, wenn die Tabelle zu irgend einem Zeitpunkt
aktualisiert wurde.
@item
Wenn Sie eine Tabelle reparieren oder prüfen und sie in Ordnung ist, wird
der Zähler auf 0 zurückgesetzt.
@item
Um Probleme zu vermeiden, die durch Interaktion mit anderen Prozessen
entstehen, die vielleicht eine Prüfung der Tabelle durchführen, wird der
Zähler beim Schließen nicht heruntergezählt, wenn er 0 war.
@end itemize

Mit anderen Worten kann der Zähler nur in folgenden Fällen nicht mehr
synchron sein:

@itemize @bullet
@item
Die @code{MyISAM}-Tabellen werden ohne @code{LOCK} und @code{FLUSH TABLES}
kopiert.
@item
MySQL ist zwischen einer Aktualisierung und dem endgültigen Schließen
abgestürzt. (Beachten Sie, dass die Tabelle trotzdem in Ordnung sein kann,
weil MySQL stets für alles zwischen jedem Statement Schreibvorgänge
durchführt.
@item
Jemand hat @code{myisamchk --repair} oder @code{myisamchk --update-state}
auf eine Tabelle ausgeführt, die durch @code{mysqld} in Benutzung war.
@item
Viele @code{mysqld}-Server benutzen die Tabelle und einer davon hat
@code{REPAIR} oder @code{CHECK} der Tabelle ausgeführt, während sie durch
einen anderen Server in Benutzung war. Hierbei kann @code{CHECK} sicher
ausgeführt werden (selbst wenn Sie Warnungen von anderen Servern erhalten
werden), aber @code{REPAIR} sollte vermieden werden, weil es momentan die
Daten-Datei durch eine neue ersetzt, was anderen Servern nicht signalisiert
wird.
@end itemize


@node MERGE, ISAM, MyISAM, Table types
@c German node MERGE
@section MERGE-Tabellen

@cindex Tabellen, Merge-
@cindex MERGE-Tabellen, Definition

@code{MERGE}-Tabellen sind neu seit MySQL-Version 3.23.25. Der Code ist
noch Gamma, sollte aber ausreichend stabil sein.

Eine @code{MERGE}-Tabelle (auch bekannt als @code{MRG_MyISAM}-Tabelle) ist
eine Sammlung identischer @code{MyISAM}-Tabellen, die wie eine benutzt
werden können. Sie können auf dieser Sammlung von Tabellen nur
@code{SELECT}, @code{DELETE} und @code{UPDATE} ausführen. Wenn Sie eine
@code{MERGE}-Tabelle löschen (@code{DROP}), löschen Sie nur die
@code{MERGE}-Spezifikation.

Beachten Sie, dass @code{DELETE FROM merge_tabelle} ohne @code{WHERE} nur
das Mapping für die Tabelle löscht, nicht alles in den gemappten Tabellen.
(Geplant ist, das in Version 4.1 zu beheben.)

Mit identischen Tabellen ist gemeint, dass alle Tabellen mit identischen
Spalten- und Schlüsselinformationen erzeugt wurden. Sie können kein MERGE
auf Tabellen ausführen, deren Spalten unterschiedlich komprimiert sind,
nicht genau dieselben Spalten oder die Schlüssel in unterschiedlicher
Reihenfolge haben. Einige der Tabellen können jedoch mit @code{myisampack}
komprimiert sein. @xref{myisampack}.

Wenn Sie eine @code{MERGE}-Tabelle erzeugen, erhalten Sie eine
@code{.frm}-Tabellendefinitionsdatei und eine
@code{.MRG}-Tabellenlistendatei. Die @code{.MRG} enthält lediglich eine
Liste der Index-Dateien (@code{.MYI}-Dateien), die wie eine benutzt werden
sollen. Alle benutzten Tabellen müssen in derselben Datenbank wie die
@code{MERGE}-Tabelle selbst sein.

Momentan benötigen Sie @code{SELECT}-, @code{UPDATE}- und
@code{DELETE}-Berechtigungen für die Tabellen, die Sie auf eine
@code{MERGE}-Tabelle mappen.

@code{MERGE}-Tabellen können bei der Lösung folgender Probleme helfen:

@itemize @bullet
@item
Auf einfache Weise einen Satz von Log-Tabellen verwalten. Beispielsweise
können Sie Daten aus unterschiedlichen Monaten in separaten Dateien
speichern, einige davon mit @code{myisampack} komprimieren und dann eine
@code{MERGE}-Tabelle erzeugen, um sie wie eine zu benutzen.
@item
Mehr Geschwindigkeit. Sie können eine große Nur-Lese-Tabelle nach
bestimmten Kriterien aufspalten und die verschiedenen Tabellenteile auf
unterschiedlichen Festplatten speichern. Eine @code{MERGE}-Tabelle darauf
könnte viel schneller sein als die große Tabelle zu benutzen. (Natürlich
können Sie auch ein RAID benutzen, um dieselben Vorteile zu erzielen.)
@item
Effizientere Suchen durchführen. Wenn Sie genau wissen, wonach Sie suchen,
können Sie mit einigen Anfragen in lediglich einer der aufgespaltenen
Tabellen suchen und die @strong{MERGE}-Tabelle für andere benutzen. Es
können sogar viele unterschiedliche @code{MERGE}-Tabellen aktiv sein,
möglicherweise mit Dateien, die sich überlappen.
@item
Effizientere Reparaturen durchführen. Es ist leichter, die individuellen
Dateien zu reparieren, die auf eine @code{MERGE}-Datei gemappt sind, als
eine wirklich große Datei zu reparieren.
@item
Sofortiges Mappen vieler Dateien als einer. Eine @code{MERGE}-Tabelle
benutzt den Index der individuellen Tabellen. Sie muss selbst keinen
eigenen Index warten. Dadurch können Sie @code{MERGE}-Tabellensammlungen
SEHR schnell erzeugen oder neu mappen. Beachten Sie, dass Sie die
Schlüsseldefinitionen angeben, wenn Sie eine @code{MERGE}-Tabelle erzeugen!
@item
Wenn Sie einen Satz von Tabellen bei Bedarf oder im Stapel zu einer großen
Tabelle vereinigen, sollten Sie statt dessen bei Bedarf eine
@code{MERGE}-Tabelle darauf erzeugen. Das ist viel schneller und spart eine
Menge Speicherplatz.
@item
Umgehen der Dateigrößengrenze des Betriebssystems.
@item
Sie können ein Alias / Synonym für eine Tabelle erzeugen, indem Sie sie
einfach ein MERGE über eine Tabelle benutzen. Das sollte keine spürbaren
Performance-Auswirkungen haben (nur eine Reihe indirekter Aufrufen und
memcpy's bei jedem Lesen).
@end itemize

Die Nachteile von @code{MERGE}-Tabellen sind:

@itemize @bullet
@item
Sie können nur identische @code{MyISAM}-Tabellen für eine
@code{MERGE}-Tabelle benutzen.
@item
@code{AUTO_INCREMENT}-Spalten werden bei @code{INSERT} nicht automatisch
aktualisiert.
@item
@code{REPLACE} funktioniert nicht.
@item
@code{MERGE}-Tabellen benutzen mehr Datei-Deskriptoren. Wenn Sie eine
@strong{MERGE} benutzen, die über 10 Tabellen mappt, und 10 Benutzer diese
benutzen, benötigen Sie 10 * 10 + 10 Datei-Deskriptoren (10 Daten-Dateien
für 10 Benutzer und 10 gemeinsam genutzte Index-Dateien).
@item
Lesevorgänge von Schlüsseln sind langsamer. Wenn Sie eine Leseoperation auf
einen Schlüssel durchführen, muss der @code{MERGE}-Handler ein Lesen auf
alle zugrunde liegenden Tabellen ausführen, um zu prüfen, welche am
nächsten zum angegebenen Schlüssel passt. Wenn Sie ein 'Lese nächsten'
ausführen, muss der @code{MERGE}-Handler die Lese-Puffer durchsuchen, um
den nächsten Schlüssel zu finden. Erst wenn ein Schlüsselpuffer
aufgebraucht ist, muss der Handler den nächsten Schlüsselblock lesen. Das
macht @code{MERGE}-Schlüssel bei @code{eq_ref}-Suchen viel langsamer, aber
nicht viel langsamer bei @code{ref}-Suchen.
@xref{EXPLAIN}.
@item
Sie können kein @code{DROP TABLE}, @code{ALTER TABLE} oder @code{DELETE
FROM tabelle} ohne eine @code{WHERE}-Klausel auf jeder Tabelle, die von
einer @code{MERGE}-Tabelle gemappt ist, ausführen, wenn diese 'offen' ist.
Wenn Sie das tun, könnte die @code{MERGE}-Tabelle immer noch auf die
Originaltabelle verweisen, und Sie würden unerwartete Ergebnisse erhalten.
@end itemize

Wenn Sie eine @code{MERGE}-Tabelle erzeugen, müssen Sie mit
@code{UNION(liste-von-tabellen)} angeben, welche Tabellen Sie wie eine
benutzen wollen. Optional können Sie mit @code{INSERT_METHOD} angeben, ob
Sie wollen, dass Einfügungen in die @code{MERGE}-Tabelle in der ersten oder
der letzten Tabelle in der @code{UNION}-Liste geschehen sollen. Wenn Sie
keine @code{INSERT_METHOD} oder @code{NO} angeben, geben alle
@code{INSERT}-Befehle auf die @code{MERGE}-Tabelle einen Fehler zurück.

Folgendes Beispiel zeigt, wie Sie @code{MERGE}-Tabellen benutzen:

@example
CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, nachricht CHAR(20));
CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, nachricht CHAR(20));
INSERT INTO t1 (nachricht) VALUES ("test"),("tabelle"),("t1");
INSERT INTO t2 (nachricht) VALUES ("test"),("tabelle"),("t2");
CREATE TABLE gesamt (a INT NOT NULL, nachricht CHAR(20), KEY(a)) TYPE=MERGE UNION=(t1,t2) INSERT_METHOD=LAST;
@end example

Beachten Sie, dass wir keinen @code{UNIQUE}- oder @code{PRIMARY
KEY}-Schlüssel in der @code{gesamt}-Tabelle angegeben haben, weil der
Schlüssel in der @code{gesamt}-Tabelle nicht eindeutig sein wird.

Beachten Sie auch, dass Sie die @code{.MRG}-Datei direkt von ausserhalb des
MySQL-Servers manipulieren können:

@example
shell> cd /mysql-data-verzeichnis/aktuelle-datenbank
shell> ls -1 t1.MYI t2.MYI > gesamt.MRG
shell> mysqladmin flush-tables
@end example

Jetzt können Sie Dinge wie folgendes tun:

@example
mysql> select * from gesamt;
+---+-----------+
| a | nachricht |
+---+-----------+
| 1 | test      |
| 2 | table     |
| 3 | t1        |
| 1 | test      |
| 2 | table     |
| 3 | t2        |
+---+-----------+
@end example

Um eine @code{MERGE}-Tabelle neu zu mappen, können Sie folgendes tun:

@itemize @bullet
@item
Die Tabelle löschen (@code{DROP}) und neu erzeugen.
@item
@code{ALTER TABLE tabelle UNION(...)} benutzen.
@item
Die @code{.MRG}-Datei ändern und ein @code{FLUSH TABLE} auf die
@code{MERGE}-Tabelle und alle zugrunde liegenden Tabellen ausführen, um den
Handler zu zwingen, die neue Definitionsdatei einzulesen.
@end itemize


@menu
* MERGE table problems::        
@end menu

@node MERGE table problems,  , MERGE, MERGE
@c German node MERGE-Tabellenprobleme
@subsection MERGE-Tabellenprobleme.

Folgende Probleme sind bei @code{MERGE}-Tabellen bekannt:

@itemize @bullet
@item
@code{DELETE FROM merge_tabelle} ohne @code{WHERE} löscht nur das Mapping
für die Tabelle, nicht alles in den gemappten Tabellen.
@item
@code{RENAME TABLE} auf eine Tabelle, die in einer aktiven
@code{MERGE}-Tabelle benutzt wird, kann die Tabelle beschädigen. Das wird
in MySQL 4.0.x behoben.
@item
Beim Erzeugen einer Tabelle des Typs @code{MERGE} wird nicht geprüft, ob
die zugrunde liegenden Tabellen kompatible Typen sind. Wenn Sie
@code{MERGE}-Tabellen in dieser Weise benutzen, ist es sehr wahrscheinlich,
dass merkwürdige Probleme auftauchen.
@item
Wenn Sie @code{ALTER TABLE} benutzen, um als erstes eine
@code{UNIQUE}-Index zu einer Tabelle hinzuzufügen, die in einer
@code{MERGE}-Tabelle benutzt wird, und dann @code{ALTER TABLE} benutzen, um
einen normalen Index auf die @code{MERGE}-Tabelle hinzuzufügen, wird die
Schlüssel-Reihenfolge für die Tabellen anders sein, wenn es einen alten,
nicht eindeutigen Schlüssel in der Tabelle gab. Das liegt daran, dass
@code{ALTER TABLE} @code{UNIQUE}-Schlüssel vor normale Schlüssel einfügt,
um in der Lage zu sein, doppelte Schlüsseleinträge so früh wie möglich zu
erkennen.
@item
Der Bereichsoptimierer kann @code{MERGE}-Tabellen noch nicht effizient
benutzen und kann manchmal nicht optimale Joins produzieren. Das wird in
MySQL 4.0.x behoben.
@item
@code{DROP TABLE} auf eine Tabelle, die in einer @code{MERGE}-Tabelle
benutzt wird, funktioniert unter Windows nicht, weil der
@code{MERGE}-Handler das Tabellen-Mapping versteckt vor der oberen Ebene
von MySQL durchführt. Weil Windows es nicht zuläßt, dass Dateien gelöscht
werden, die offen sind, müssen Sie zuerst alle @code{MERGE}-Tabellen auf
Platte zurückschreiben (mit @code{FLUSH TABLES}) oder die
@code{MERGE}-Tabelle löschen, bevor Sie die Tabelle löschen. Das wird zu
dem Zeitpunkt behoben, wenn Sichten (@code{VIEW}s) eingeführt werden.
@end itemize

@node ISAM, HEAP, MERGE, Table types
@c German node ISAM
@section ISAM-Tabellen

@cindex tables, ISAM

Sie können auch den veralteten @code{ISAM}-Tabellentyp benutzen. Dieser
wird recht bald verschwinden (wahrscheinlich in MySQL 4.1), weil
@code{MyISAM} eine bessere Implementation derselbe Sache ist. @code{ISAM}
benutzt einen @code{B-tree}-Index. Der Index wird in einer Datei mit der
Endung @code{.ISM} gespeichert, und die Daten in einer Datei mit der Endung
@code{.ISD}. Sie können @code{ISAM}-Tabellen mit dem
@code{isamchk}-Dienstprogramm prüfen / reparieren. @xref{Disaster Prevention}.

@code{ISAM} hat folgende Features / Eigenschaften:

@itemize @bullet
@item Komprimierte und Festlängen-Schlüssel
@item Feste und dynamische Datensatzlängen
@item 16 Schlüssel mit 16 Schlüsselteilen pro Schlüssel
@item Maximale Schlüssellänge 256 (Vorgabe)
@item Daten werden im Maschinenformat gespeichert. Das ist schnell, aber
Maschinen- / Betriebssystem-abhängig.
@end itemize

Die meisten Dinge, die für @code{MyISAM}-Tabellen gelten, gelten auch für
@code{ISAM}-Tabellen. @xref{MyISAM}. Die größten Unterschiede im Vergleich
zu @code{MyISAM} sind:

@itemize @bullet
@item @code{ISAM}-Tabellen sind nicht binärportabel zwischen verschiedenen
Betriebssystemen / Plattformen.
@item Handhabt keine Tabellen > 4 GB.
@item Unterstützt nur Präfix-Komprimierung von Zeichenketten.
@item Kleinere Schlüssel-Beschränkungen.
@item Dynamische Tabelle werden schneller fragmentiert.
@item Tabellen werden mit @code{pack_isam} statt mit @code{myisampack}
komprimiert.
@end itemize

Wenn Sie eine @code{ISAM}-Tabelle in eine @code{MyISAM}-Tabelle umwandeln
wollen, können Sie Dienstprogramme wie @code{mysqlcheck} oder ein
@code{ALTER TABLE}-Statement benutzen:

@example
mysql> ALTER TABLE tabelle TYPE = MYISAM;
@end example

Die eingebetteten (embedded) MySQL-Versionen unterstützen keine
@code{ISAM}-Tabellen.

@node HEAP, InnoDB, ISAM, Table types
@c German node HEAP
@section HEAP-Tabellen

@cindex Tabellen, @code{HEAP}

@code{HEAP}-Tabellen benutzen eine gehashten Index und werden im
Arbeitsspeicher gespeichert. Das macht sie sehr schnell, aber wenn MySQL
abstürzt, verlieren Sie alle darin gespeicherten Daten. @code{HEAP} ist
sehr nützlich für temporäre Tabellen.

Die MySQL-internen @code{HEAP}-Tabellen benutzen 100% dynamisches Hashen
ohne Overflow-Bereiche. Es wird kein zusätzlicher Platz für freie Listen
benötigt. @code{HEAP}-Tabellen haben auch keine Probleme mit Löschen plus
Einfügen, was normalerweise bei gehashten Tabellen häufig vorkommt:

@example
mysql> CREATE TABLE test TYPE=HEAP SELECT ip,SUM(downloads) as down
        FROM log_tabelle GROUP BY ip;
mysql> SELECT COUNT(ip),AVG(down) FROM test;
mysql> DROP TABLE test;
@end example

Einige Dinge sollten Sie bei der Benutzung von @code{HEAP}-Tabellen in
Betracht ziehen:

@itemize @bullet
@item
Sie sollten immer @code{MAX_ROWS} im @code{CREATE}-Statement angeben, um
sicherzustellen, dass Sie nicht versehentlich den gesamten Arbeitsspeicher
benutzen.
@item
Indexe werden nur bei @code{=} und @code{<=>} benutzt (sind aber SEHR
schnell).
@item
@code{HEAP}-Tabellen können nur ganze Schlüssel benutzen, um nach einer
Zeile zu suchen. Vergleichen Sie das mit @code{MyISAM}-Tabellen, bei denen
jedes Präfix des Schlüssels für das Suchen von Zeilen benutzt werden kann.
@item
@code{HEAP}-Tabellen benutzen ein festes Datensatzlängenformat.
@item
@code{HEAP} unterstützt keine @code{BLOB}/@code{TEXT}-Spalten.
@item
@code{HEAP} unterstützt keine @code{AUTO_INCREMENT}-Spalten.
@item
@code{HEAP} unterstützt keinen Index auf eine @code{NULL}-Spalte.
@item
Es darf keine nicht eindeutigen Schlüssel auf eine @code{HEAP}-Tabelle
geben (das ist ungebräuchlich für gehashte Tabellen).
@item
@code{HEAP}-Tabellen werden von allen Clients gemeinsam benutzt (so wie
jede andere Tabelle).
@item
Sie können nicht nach dem nächsten Eintrag in der Reihenfolge suchen (also
den Index benutzen, um ein @code{ORDER BY} zu machen).
@item
Die Daten für @code{HEAP}-Tabellen werden in kleinen Blöcken zugewiesen.
Die Tabellen sind 100% dynamisch (beim Einfügen). Es werden keine
Overflow-Bereiche und kein zusätzlicher Platz für Schlüssel benötigt.
Gelöschte Zeilen werden in eine verknüpfte Liste geschrieben und wieder
benutzt, wenn Sie neue Daten in die Tabelle einfügen.
@item
Sie brauchen genug zusätzlichen Arbeitsspeicher für alle
@code{HEAP}-Tabellen, die Sie zugleich benutzen wollen.
@item
Um Speicher freizugeben, führen Sie @code{DELETE FROM heap_tabelle},
@code{TRUNCATE heap_tabelle} oder @code{DROP TABLE heap_tabelle} aus.
@item
MySQL kann nicht herausfinden, wie viele Zeilen es zwischen zwei Werten
ungefähr gibt (das wird vom Bereichsoptimierer benötigt, um zu entscheiden,
welcher Index benutzt wird). Das kann einige Anfragen betreffen, wenn Sie
eine @code{MyISAM}-Tabelle in eine @code{HEAP}-Tabelle umwandeln.
@item
Um sicherzustellen, dass Sie nicht versehentlich etwas Unkluges tun, können
Sie keine @code{HEAP}-Tabellen größer als @code{max_heap_table_size}
erzeugen.
@end itemize

Der für eine Zeile in einer @code{HEAP}-Tabelle benötigte Speicher ist:

@example
SUM_OVER_ALL_KEYS(max_length_of_key + sizeof(char*) * 2)
+ ALIGN(length_of_row+1, sizeof(char*))
@end example

@code{sizeof(char*)} ist 4 auf 32-Bit-Maschinen und 8 auf 64-Bit-Maschinen.


@node InnoDB, BDB, HEAP, Table types
@c German node InnoDB
@section InnoDB-Tabellen



@menu
* InnoDB overview::             
* InnoDB start::                
* InnoDB init::                 
* Using InnoDB tables::         
* Adding and removing::         
* Backing up::                  
* Moving::                      
* InnoDB transaction model::    
* Implementation::              
* Table and index::             
* File space management::       
* Error handling::              
* InnoDB restrictions::         
* InnoDB contact information::  
@end menu

@node InnoDB overview, InnoDB start, InnoDB, InnoDB
@c German node Überblick über InnoDB
@subsection Überblick über InnoDB-Tabellen

@cindex Transaktionen, Unterstützung
@cindex transaktionssichere Tabellen
@cindex ACID

InnoDB stellt MySQL einen transaktionssicheren (@code{ACID}-kompatiblen)
Tabellen-Handler mit Fähigkeiten für Commit, Rollback und Reparatur nach
Absturz zur Verfügung. InnoDB beherrscht Sperren auf Zeilenebene sowie ein
konsistentes, nicht sperrendes Lesen in der Art von Oracle bei
@code{SELECT}s. Diese Features steigern die Handhabung gleichzeitiger
Verbindungen und die Performance. Es gibt bei InnoDB keine Notwendigkeit
für Sperr-Eskalation, weil die Sperren auf Zeilenebene bei InnoDB in sehr
wenig Speicherplatz passen. InnoDB-Tabellen unterstützen als erster
Tabellentyp in MySQL @code{FOREIGN KEY}-Beschränkungen.

InnoDB wurde für maximale Performance bei der Bearbeitung großer
Datenmengen entworfen. Seine Prozessor-Effizienz wird wahrscheinlich von
keiner anderen Festplatten-basierenden relationalen Datenbank-Engine
erreicht.

Technisch gesehen ist InnoDB ein komplettes Datenbank-Backend, das unter
MySQL platziert ist. InnoDB hat seinen eigenen Puffer-Pool, um Daten und
Indexe im Hauptspeicher zu cachen. InnoDB speichert seine Tabellen und
Indexe in einem Tabellenplatz (Tablespace), der aus mehreren Dateien
bestehen kann. Das unterscheidet sich beispielsweise von MyISAM-Tabellen,
bei denen jede Tabelle als separate Datei gespeichert ist. InnoDB-Tabellen
können jede beliebige Größe annehmen, sogar auf Betriebssystemen, deren
Dateigröße auf 2 GB beschränkt ist.

Die neuesten Informationen über InnoDB finden Sie unter
@uref{http://www.innodb.com/}. Die aktuellste Version des InnoDB-Handbuchs
ist immer dort zu finden, und Sie können auch kommerzielle Lizenzen und
kommerziellen Support für InnoDB bestellen.

InnoDB wird momentan (Oktober 2001) für die Produktion auf mehreren großen
Datenbank-Sites benutzt, die hohe Performance benötigen. Die bekannte
Internet-Newssite Slashdot.org läuft auf InnoDB. Mytrix Inc. speichert über
1 TB an Daten in InnoDB, und eine andere Site handhabt eine
durchschnittliche Last von 800 Einfüge- und Update-Operationen pro Sekunde
mit InnoDB.

InnoDB-Tabellen sind in der MySQL-Quelldistribution ab Version 3.23.34a
enthalten und in der MySQL-Max-Binärversion aktiviert. Für Windows sind die
Max-Binärdateien in der Standarddistribution enthalten.

Wenn Sie eine Binärversion von MySQL herunter geladen haben, die
Unterstützung für InnoDB enthält, folgen Sie einfach den Anweisungen im
Handbuch für die Installation einer Binärversion von MySQL. Wenn Sie
bereits MySQL-3.23 installiert haben, können Sie MySQL-Max am einfachsten
installieren, indem Sie die ausführbare Datei für den Server
(@file{mysqld}) durch die entsprechende ausführbare Datei in der
Max-Distribution ersetzen. MySQL and MySQL-Max unterscheiden sich nur in
Bezug auf die ausführbare Datei für den Server. @xref{MySQL binaries}. @xref{mysqld-max, , @code{mysqld-max}}.

@c German FIX changed @xref to @ref
Um MySQL mit InnoDB-Unterstützung zu kompilieren, laden Sie MySQL-3.23.34a
oder neuer von @uref{http://www.mysql.com/} herunter und konfigurieren Sie
MySQL mit der @code{--with-innodb}-Option. Sehen Sie im Handbuch unter
@ref{Installing source} nach.

@example
cd /pfad/zur/quelldistribution/von/mysql-3.23.37
./configure --with-innodb
@end example

Um InnoDB zu benutzen, müssen Sie InnoDB init in Ihrer @file{my.cnf}- oder
@file{my.ini}-Datei angeben. In dieser Datei müssen Sie mindestens
folgenden Zeile im @code{[mysqld]}-Abschnitt hinzufügen:

@example
innodb_data_file_path=ibdata:30M
@end example

@c German FIX changed @xref to @ref
Für eine gute Performance ist es jedoch am besten, Optionen wie die unten
im Abschnitt @ref{InnoDB start} empfohlenen anzugeben.

InnoDB wird unter der GNU-GPL-Lizenz Version 2 (vom Juni 1991) vertrieben.
In den Quelldistributionen von MySQL erscheint InnoDB als Unterverzeichnis.


@node InnoDB start, InnoDB init, InnoDB overview, InnoDB
@c German node Mit InnoDB anfangen
@subsection Mit InnoDB anfangen - Optionen

Um InnoDB-Tabellen in MySQL-Max-3.23 zu benutzen, @strong{MÜSSEN} Sie
Konfigurationsparameter im @code{[mysqld]}-Abschnitt der
MySQL-Konfigurationsdatei @file{my.cnf} angeben. @xref{Option files}.

Der einzige erforderliche Parameter, um InnoDB in MySQL-Max-3.23 benutzen
zu können, ist @code{innodb_data_file_path}.
In MySQL-4.0 müssen Sie nicht einmal @code{innodb_data_file_path} angeben.
Vorgabemäßig wird eine 64 MB große Daten-Datei @file{ibdata1} im
@code{datadir} von MySQL erzeugt.

Um jedoch eine gute Performance zu erzielen, MÜSSEN Sie explizit die unten
in Beispielen aufgeführten InnoDB-Parameter setzen.

Der Vorgabewert für @code{innodb_data_home_dir} ist das @code{datadir} von
MySQL. Wenn Sie @code{innodb_data_home_dir} nicht angeben, können Sie in
@code{innodb_data_file_path} keine absoluten Pfade benutzen.

Nehmen wir an, Sie haben eine Windows-NT-Maschine mit 128 MB RAM und einer
einzelnen 10 GB großen Festplatte. Unten steht ein Beispiel von möglichen
Konfigurationsparametern in @file{my.cnf} für InnoDB:

@example
[mysqld]
# Hier können Ihre sonstigen MySQL-Serveroptionen stehen
# ...
#
innodb_data_home_dir = c:\ibdata
# Die Daten-Dateien müssen in der Lage sein,
# Ihre Daten und Indexe aufzunehmen
innodb_data_file_path = ibdata1:2000M;ibdata2:2000M
# Puffer-Poolgröße auf 50% bis 80%
# des Arbeitsspeichers Ihres Computers setzen
set-variable = innodb_buffer_pool_size=70M
set-variable = innodb_additional_mem_pool_size=10M
innodb_log_group_home_dir = c:\iblogs
# .._log_arch_dir muss dasselbe sein wie
# .._log_group_home_dir
innodb_log_arch_dir = c:\iblogs
innodb_log_archive=0
set-variable = innodb_log_files_in_group=3
# Die Log-Dateigröße auf ungefähr 15%
# der Puffer-Poolgröße setzen
set-variable = innodb_log_file_size=10M
set-variable = innodb_log_buffer_size=8M
# ..flush_log_at_trx_commit auf 0 setzen,
# wenn Sie es sich leisten können,
# ein paar der letzten Transaktionen zu verlieren
innodb_flush_log_at_trx_commit=1
set-variable = innodb_file_io_threads=4
set-variable = innodb_lock_wait_timeout=50
@end example

Beachten Sie, dass die Daten-Dateien bei einigen Betriebssystemen kleiner
als 2 GB sein müssen! Die Gesamtgröße von Daten-Dateien muss größer oder
gleich 10 MB sein. Die Gesamtgröße der Log-Dateien MUSS auf
32-Bit-Computern kleiner als 4 GB sein.

@strong{InnoDB legt keine Verzeichnisse an. Diese müssen Sie selbst
erzeugen!}
Stellen Sie auch sicher, dass der MySQL-Server Rechte hat, Dateien in den
Verzeichnissen anzulegen, die Sie angeben.
 
Wenn Sie zum ersten Mal eine InnoDB-Datenbank erzeugen, sollten Sie den
MySQL-Server am besten von der Kommandozeilen-Eingabeaufforderung starten.
InnoDB gibt dann Informationen über die Datenbank-Erzeugung auf dem
Bildschirm aus und Sie sehen, was passiert. Unten in Abschnitt 3 sehen Sie,
wie die Ausgaben aussehen sollten.
Unter Windows können Sie @file{mysqld-max.exe} so starten:
@example
ihr-pfad-zu-mysqld>mysqld-max --standalone --console
@end example

Nehmen wir an, Sie haben einen Linux-Computer mit 512 MB RAM und drei
Festplatten mit jeweils 20 GB (in Verzeichnispfaden @file{/}, @file{/dr2}
and @file{/dr3}). Unten ist ein Beispiel möglicher Konfigurationsparameter
in @file{my.cnf} für InnoDB:

@example
[mysqld]
# Hier können Ihre sonstigen MySQL-Serveroptionen stehen
# ...
#
innodb_data_home_dir = /
# Die Daten-Dateien müssen in der Lage sein,
# Ihre Daten und Indexe aufzunehmen
innodb_data_file_path = ibdata/ibdata1:2000M;dr2/ibdata/ibdata2:2000M
# Puffer-Poolgröße auf 50% bis 80%
# des Arbeitsspeichers Ihres Computers setzen
set-variable = innodb_buffer_pool_size=350M
set-variable = innodb_additional_mem_pool_size=20M
innodb_log_group_home_dir = /dr3/iblogs
# .._log_arch_dir muss dasselbe sein wie
# .._log_group_home_dir
innodb_log_arch_dir = /dr3/iblogs
innodb_log_archive=0
set-variable = innodb_log_files_in_group=3
# Die Log-Dateigröße auf ungefähr 15%
# der Puffer-Poolgröße setzen
set-variable = innodb_log_file_size=50M
set-variable = innodb_log_buffer_size=8M
# ..flush_log_at_trx_commit auf 0 setzen,
# wenn Sie es sich leisten können,
# ein paar der letzten Transaktionen zu verlieren
innodb_flush_log_at_trx_commit=1
set-variable = innodb_file_io_threads=4
set-variable = innodb_lock_wait_timeout=50
#innodb_flush_method=fdatasync
#innodb_fast_shutdown=1
#set-variable = innodb_thread_concurrency=5
@end example

Beachten Sie, dass die beiden Daten-Dateien auf unterschiedliche Platten
platziert wurden. Der Grund für den Namen @code{innodb_data_file_path}
ist, dass Sie auch Pfade zu Ihren Daten-Dateien angeben können und dass
@code{innodb_data_home_dir} nur textlich mit Ihren Daten-Datei-Pfaden
verkettet wird, wobei ein möglicher Schrägstrich oder Backslash dazwischen
hinzugefügt wird. InnoDB füllt den Tabellenplatz (Tablespace), der durch
die Daten-Dateien gebildet wird, von unten nach oben. In manchen Fällen
verbessert es die Performance der Datenbank, wenn nicht alle Daten auf
derselben physikalischen Festplatte platziert sind. Es verbessert häufig
die Performance, Log-Dateien auf anderen Platten als die Daten zu
platzieren.

Die Bedeutung der Konfigurationsparameter ist wie folgt:

@multitable @columnfractions .30 .70
@item @strong{Option} @tab @strong{Beschreibung}
@item @code{innodb_data_home_dir} @tab 
Der allgemeine Teil des Verzeichnispfads für alle InnoDB-Daten-Dateien. Die
Vorgabe für diesen Parameter ist das @code{datadir} von MySQL.
@item @code{innodb_data_file_path} @tab 
Pfade zu individuellen Daten-Dateien und ihre Größen. Der volle
Verzeichnispfad zu jeder Daten-Datei wird durch Verkettung von
innodb_data_home_dir mit den hier angegebenen Pfaden hergestellt. Die
Dateigrößen werden in Megabytes angegeben, daher das 'M' nach der obigen
Angabe. InnoDB versteht auch die Abkürzung 'G', 1G bedeutet 1024M. Ab
3.23.44 können Sie die Dateigröße auf mehr als 4 GB setzen, wenn das
Betriebssystem große Dateien unterstützt. Auf einige Betriebssystemen
müssen Dateien kleiner als 2 GB sein. Die Summe der Dateigrößen muss
mindestens 10 MB betragen.
@item @code{innodb_mirrored_log_groups} @tab 
Anzahl identischer Kopien von Log-Gruppen, die für die Datenbank gehalten
werden. Momentan sollte dieser Parameter auf 1 gesetzt werden.
@item @code{innodb_log_group_home_dir} @tab 
Verzeichnispfad zu den InnoDB-Log-Dateien.
@item @code{innodb_log_files_in_group} @tab 
Anzahl von Log-Dateien in der Log-Gruppe. InnoDB schreibt in zirkulärer
Weise in die Dateien. Hier wird ein Wert 3 empfohlen.
@item @code{innodb_log_file_size} @tab 
Größe jeder Log-Datei in einer Log-Gruppe in Megabytes. Sinnvolle Werte
reichen von 1 MB bis 1/n-tel der Größe des Puffer-Pools, die unten
angegeben wird, wobei n die Anzahl der Log-Dateien in der Gruppe ist. Je
größer der Wert, desto weniger Checkpoint-Flush-Aktivität wird im Puffer
benötigt, was Festplatten-Ein- und -Ausgaben erspart. Größere Log-Dateien
bedeutet jedoch auch, dass die Wiederherstellung im Fall eines Absturzes
langsamer ist. Die Gesamtgröße aller Log-Dateien muss auf 32-Bit-Computern
kleiner als 4 GB sein.
@item @code{innodb_log_buffer_size} @tab 
Die Größe des Puffers, den InnoDB benutzt, um in die Log-Dateien auf
Platte zu schreiben. Sinnvolle Werte liegen im Bereich von 1 MB bis zur
Hälfte der Gesamtgröße der Log-Dateien. Ein großer Log-Puffer erlaubt,
dass große Transaktionen laufen können, ohne dass die Notwendigkeit
besteht, das Log auf Platte zu schreiben, bis die Transaktion abgeschickt
(commit) wird. Wenn Sie daher große Transaktionen haben, sparen Sie
Festplatten-Ein- und Ausgaben, wenn Sie den Log-Puffer Groß machen.
@item @code{innodb_flush_log_at_trx_commit} @tab 
Normalerweise wird dieser Parameter auf 1 gesetzt, was bedeutet, dass beim
Abschicken (commit) einer Transaktion das Log auf Platte geschrieben wird 
(flush) und die durch die Transaktion gemachten Änderungen permanent werden
und einen Datenbankabsturz überleben. Wenn Sie willens sind, in Bezug auf
diese Sicherheit Kompromisse einzugeben und eher kleine Transaktionen
laufen lassen, können Sie diesen Wert auf 0 setzen, um Festplatten-Ein- und
-Ausgaben in Bezug auf die Log-Dateien zu verringern.
@item @code{innodb_log_arch_dir} @tab 
Das Verzeichnis, in dem komplett geschriebene Log-Dateien archiviert
werden, wenn Archivierung benutzt wird. Der Wert dieses Parameters sollte
momentan derselbe sein wie @code{innodb_log_group_home_dir}.
@item @code{innodb_log_archive} @tab 
Dieser Wert sollte momentan auf 0 gesetzt werden. Weil MySQL die
Wiederherstellung aus einer Datensicherung unter Benutzung seiner eigenen
Log-Dateien durchführt, gibt es momentan keine Notwendigkeit,
InnoDB-Log-Dateien zu archivieren.
@item @code{innodb_buffer_pool_size} @tab 
Die Größe des Speicherpuffers, den InnoDB benutzt, um Daten und Indexe
seiner Tabellen zu cachen. Je größer Sie diesen Wert setzen, desto weniger
Festplatten-Ein- und -Ausgaben werden für den Zugriff auf Daten in Tabellen
benötigt. Auf einem dedizierten Datenbank-Server können Sie diesen
Parameter auf bis zu 80% des physikalischen Arbeitsspeichers der Maschine
setzen. Setzen Sie ihn allerdings nicht zu hoch, weil bei manchen
Betriebssystemen der Wettbewerb um Arbeitsspeicher zu Paging führt.
@item @code{innodb_additional_mem_pool_size} @tab 
Die Größe des Speicher-Pools, den InnoDB für die Speicherung von
Daten-Wörterbuchinformationen und anderen internen Datenstrukturen benutzt.
Ein sinnvoller Wert hierfür könnte 2 MB sein. Je mehr Tabellen Sie jedoch
in Ihrer Applikation haben, desto mehr müssen Sie hier zuweisen. Wenn
InnoDB in diesem Pool keinen Speicherplatz mehr hat, läßt es sich
Speicherplatz vom Betriebssystem zuweisen und schreibt Warnmeldungen in die
MySQL-Fehler-Log-Datei.
@item @code{innodb_file_io_threads} @tab 
Die Anzahl der Datei-Ein- und -Ausgabe-Threads in InnoDB. Normalerweise
sollte dieser Wert 4 sein, aber Windows-Festplatten könnten von einer
höheren Zahl profitieren.
@item @code{innodb_lock_wait_timeout} @tab 
Timeout in Sekunden. Solange wartet eine InnoDB-Transaktion auf eine
Sperre, bevor sie abgebrochen (Rollback) wird. InnoDB erkennt automatisch
Transaktionsblockierungen in seiner eigenen Sperr-Tabelle und bricht die
Transaktion ab (Rollback). Wenn Sie den @code{LOCK TABLES}-Befehl oder
andere transaktionssichere Tabellen-Handler als InnoDB in derselben
Transaktion benutzen, kann eine Blockierung auftreten, die InnoDB nicht
erkennen kann. In solchen Fällen ist ein Timeout nützlich, um die Situation
zu bereinigen.
@item @code{innodb_flush_method} @tab
(Verfügbar ab Version 3.23.40.)
Der Vorgabewert hierfür ist @code{fdatasync}.
Ein andere Option ist @code{O_DSYNC}.
@end multitable
 

@node InnoDB init, Using InnoDB tables, InnoDB start, InnoDB
@c German node InnoDB initialisieren
@subsection InnoDB-Tabellenplatz (Tablespace) erzeugen

Angenommen, Sie haben MySQL installiert und @file{my.cnf} so editiert, dass
sie die notwendigen InnoDB Konfigurationsparameter enthält. Bevor Sie MySQL
starten, sollten Sie überprüfen, dass die für InnoDB-Daten- und Log-Dateien
angegebenen Verzeichnisse existieren und dass Sie auf diese Zugriffsrechte
haben. InnoDB kann keine Verzeichnisse anlegen, nur Dateien. Überprüfen Sie
auch, ob Sie auf der Festplatte genug Platz für Daten- und Log-Dateien
haben.

Wenn Sie jetzt MySQL starten, fängt InnoDB an, Ihre Daten- und Log-Dateien
zu erzeugen. InnoDB gibt dabei etwas wie das folgende aus:

@example
~/mysqlm/sql > mysqld
InnoDB: The first specified data file /home/stefan/data/ibdata1 did not exist:
InnoDB: a new database to be created!
InnoDB: Setting file /home/stefan/data/ibdata1 size to 134217728
InnoDB: Database physically writes the file full: wait...
InnoDB: Data file /home/stefan/data/ibdata2 did not exist: new to be created
InnoDB: Setting file /home/stefan/data/ibdata2 size to 262144000
InnoDB: Database physically writes the file full: wait...
InnoDB: Log file /home/stefan/data/logs/ib_logfile0 did not exist: new to be created
InnoDB: Setting log file /home/stefan/data/logs/ib_logfile0 size to 5242880
InnoDB: Log file /home/stefan/data/logs/ib_logfile1 did not exist: new to be created
InnoDB: Setting log file /home/stefan/data/logs/ib_logfile1 size to 5242880
InnoDB: Log file /home/stefan/data/logs/ib_logfile2 did not exist: new to be created
InnoDB: Setting log file /home/stefan/data/logs/ib_logfile2 size to 5242880
InnoDB: Started
mysqld: ready for connections
@end example

Jetzt wurde eine neue InnoDB-Datenbank erzeugt. Sie können sich mit den
üblichen MySQL-Client-Programmen wie @code{mysql} mit dem MySQL-Server
verbinden. Wenn Sie den MySQL-Server mit @file{mysqladmin shutdown}
herunter fahren, gibt InnoDB etwa wie das folgende aus:

@example
010321 18:33:34  mysqld: Normal shutdown
010321 18:33:34  mysqld: Shutdown Complete
InnoDB: Starting shutdown...
InnoDB: Shutdown completed
@end example

Wenn Sie jetzt einen Blick auf die Daten-Dateien und Log-Verzeichnisse
werfen, sehen Sie die erzeugten Dateien. Das Log-Verzeichnis enthält auch
eine kleine Datei namens @file{ib_arch_log_0000000000}. Diese Datei
resultiert aus der Datenbank-Erzeugung, nach der InnoDB die
Log-Archivierung ausgeschaltet hat. Wenn MySQL noch einmal gestartet wird,
sieht die Ausgabe etwa wie folgt aus:

@example
~/mysqlm/sql > mysqld
InnoDB: Started
mysqld: ready for connections
@end example



@menu
* Error creating InnoDB::       
@end menu

@node Error creating InnoDB,  , InnoDB init, InnoDB init
@c German node Fehler bei der Erzeugung von InnoDB
@subsubsection Falls etwas bei der Datenbank-Erzeugung schiefgeht

Falls etwas bei der Datenbank-Erzeugung schiefgeht, sollten Sie alle durch
InnoDB erzeugten Dateien löschen. Das heißt alle Daten-Dateien, alle
Log-Dateien, die kleine archivierte Log-Datei und - falls Sie bereits
InnoDB-Tabellen erzeugt haben, auch die entsprechenden @file{.frm}-Dateien
für diese Tabellen in den MySQL-Datenbankverzeichnissen. Danach können Sie
die InnoDB-Datenbankerzeugung erneut versuchen.


@node Using InnoDB tables, Adding and removing, InnoDB init, InnoDB
@c German node InnoDB-Tabellen benutzen
@subsection InnoDB-Tabellen erzeugen

Angenommen, Sie haben den MySQL-Client mit dem Befehl @code{mysql test}
gestartet. Um eine Tabelle im InnoDB-Format zu erzeugen, müssen Sie im
SQL-Befehl zur Tabellenerzeugung @code{TYPE = InnoDB} angeben:

@example
CREATE TABLE kunde (A INT, B CHAR (20), INDEX (A)) TYPE = InnoDB;
@end example

Dieser SQL-Befehl erzeugt eine Tabelle und einen Index auf die Spalte
@code{A} im InnoDB-Tabellenplatz (Tablespace), der aus den Daten-Dateien
besteht, die Sie in @file{my.cnf} angegeben haben. MySQL erzeugt zusätzlich
eine Datei @file{kunde.frm} im MySQL-Datenbankverzeichnis @file{test}.
Intern fügt InnoDB seinem eigenen Datenwörterbuch einen Eintrag für die
Tabelle @code{'test/kunde'} hinzu. Wenn Sie daher eine Tabelle namens
@code{kunde} in einer anderen Datenbank von MySQL erzeugen, kollidieren die
Tabellennamen innerhalb InnoDB nicht.

Sie können den freien Speicherplatz im InnoDB-Tabellenplatz (Tablespace)
mit dem Tabellen-Status-Befehl von MySQL für jede Tabelle, die Sie mit
@code{TYPE = InnoDB} erzeugt haben, abfragen. Die Menge freien Platzes im
Tabellenplatz (Tablespace) erscheint im Kommentar-Abschnitt der Tabelle in
der Ausgabe von @code{SHOW}. Beispiel:

@example
SHOW TABLE STATUS FROM test LIKE 'kunde'
@end example

Beachten Sie, dass die Statistiken, die @code{SHOW} über InnoDB-Tabellen
ausgibt, nur Näherungswerte sind: Sie werden für die SQL-Optimierung
benutzt. Die für Tabelle und Indexe reservierten Größen in Bytes sind
allerdings genau.

@subsubsection MyISAM-Tabellen in InnoDB-Tabellen umwandeln

InnoDB hat keine spezielle Optimierung für separate Index-Erzeugung. Daher
lohnt es sich nicht, die Tabelle zu exportieren und importieren und die
Indexe danach zu erzeugen. Die schnellste Art, eine Tabelle in InnoDB zu
ändern, ist, die Einfügungen direkt in eine InnoDB-Tabelle vorzunehmen,
das heißt, @code{ALTER TABLE ... TYPE=INNODB} zu benutzen oder eine leere
InnoDB-Tabelle mit identischen Definitionen zu nehmen und die Zeilen mit
@code{INSERT INTO ... SELECT * FROM ...} einzufügen.

Um eine bessere Kontrolle über den Einfügeprozess zu erhalten, kann es
besser sein, große Tabellen in Teilstücken einzufügen:

@example
INSERT INTO neue_tabelle SELECT * FROM alte_tabelle WHERE schluessel > etwas
                                             AND schluessel <= etwas_anderes;
@end example

Nachdem alle Daten eingefügt wurden, können Sie die Tabellen umbenennen.

Während der Umwandlung großer Tabellen sollten Sie den InnoDB-Puffer-Pool
hoch setzen, um Festplatten-Ein- und -Ausgaben zu verringern, allerdings
nicht höher als 80% des physikalischen Arbeitsspeichers. Sie sollten die
InnoDB-Log-Dateien Groß machen und auch den Log-Puffer.

Stellen Sie sicher, dass Sie genug Tabellenplatz (Tablespace) haben!
InnoDB-Tabellen benötigen viel mehr Platz als MyISAM-Tabellen. Wenn ein
@code{ALTER TABLE} nicht mehr genug Platz hat, wird ein Rollback gestartet,
das Stunden dauern kann, wenn es auf der Festplatte stattfindet. Bei
Einfügeoperationen verwendet InnoDB den Einfügepuffer, um sekundäre
Index-Datensätze mit Indexen in Stapeln zu vermischen. Das spart eine Menge
an Festplatten-Ein- und -Ausgaben. Beim Rollback wird kein solcher
Mechanismus benutzt, weshalb das Rollback bis zu 30 mal länger als das
Einfügen dauern kann.

Falls Sie keine wertvollen Daten in Ihren InnoDB-Dateien haben, ist es im
Fall eines 'festgefahrenen' Rollback besser, den Datenbank-Prozess zu
killen und alle InnoDB-Daten- und Log-Dateien sowie alle InnoDB-Tabellen
(@file{.frm}-Dateien) zu löschen und noch einmal anzufangen, statt darauf
zu warten, dass Millionen von Festplatten-Ein- und -Ausgaben beendet
werden.

@subsubsection  Fremdschlüssel-(Foreign Key)-Beschränkungen

InnoDB-Version 3.23.44 hat Fremdschlüssel-(Foreign Key)-Beschränkungen.
InnoDB ist der erste MySQL-Tabellentyp, der die Definition von
Fremdschlüssel-Beschränkungen zuläßt, um die Integrität Ihrer Daten zu
überwachen.

Die Syntax einer Fremdschlüsseldefinition in InnoDB:
@example
FOREIGN KEY (index_spalten_name, ...) REFERENCES tabellen_name (index_spalten_name, ...)
@end example

Beispiel:

@example
CREATE TABLE eltern(id INT NOT NULL, PRIMARY KEY (id)) TYPE=INNODB;
CREATE TABLE kind(id INT, eltern_id INT, INDEX par_ind (eltern_id),
           FOREIGN KEY (eltern_id) REFERENCES eltern(id)) TYPE=INNODB;
@end example

Beide Tabellen müssen vom Typ InnoDB sein und es muss einen Index geben,
bei dem der Fremdschlüssel und der referenzierte Schlüssel als erste
Spalten aufgeführt sind. Jegliches @code{ALTER TABLE} entfernt momentan
alle Fremdschlüsselbeschränkungen, die für die Tabelle definiert wurden,
aber nicht die Beschränkungen, die die Tabelle referenzieren.
Korrespondierende Spalten im Fremdschlüssel und dem referenzierten
Schlüssel müssen ähnliche interne Datentypen innerhalb InnoDB sein, so dass
sie ohne Typumwandlung verglichen werden können. Die Längen von
Zeichenkettentypen müssen nicht dieselben sein. Die Größe und Vorzeichen /
kein Vorzeichen von Ganzzahltypen müssen dieselben sein.

Beim Prüfen von Fremdschlüsseln setzt InnoDB gemeinsame Sperren auf
Zeilenebene auf kind- und eltern-Datensätze, die es betrachten muss. InnoDB
prüft Fremdschlüssel-(Foreign Key)-Beschränkungen sofort: Die Prüfung wird
nicht bis zu einem Transaktions-Commit verschoben.

InnoDB läßt zu, dass jegliche Tabelle gelöscht wird, selbst wenn das die
Fremdschlüssel-(Foreign Key)-Beschränkungen durchbrechen würde, die die
Tabelle referenzieren. Wenn Sie eine Tabelle löschen, werden die
Beschränkungen, die in ihrem CREATE-Statement definiert wurden, ebenfalls
gelöscht.

Wenn Sie eine gelöschte Tabelle neu erzeugen, muss sie eine Definition
haben, die mit den Fremdschlüssel-(Foreign Key)-Beschränkungen konform ist,
die sie referenzieren. Sie muss die richten Spaltennamen und -typen haben,
und sie muss - wie oben angegeben - Indexe auf die referenzierten Schlüssel
haben.

Sie können die Fremdschlüssel-(Foreign Key)-Beschränkungen für eine Tabelle
wie folgt auflisten:
@code{T} with
@example
SHOW TABLE STATUS FROM ihr_datenbank_name LIKE 'T';
@end example
Die Fremdschlüssel-(Foreign Key)-Beschränkungen werden im
Tabellen-Kommentar der Ausgabe aufgelistet.

InnoDB unterstützt noch kein @code{CASCADE ON DELETE} oder andere spezielle
Optionen für diese Beschränkungen.

@node Adding and removing, Backing up, Using InnoDB tables, InnoDB
@c German node Hinzufügen und entfernen
@subsection Hinzufügen und Entfernen von InnoDB-Daten- und -Log-Dateien

Sie können die Größe einer InnoDB-Daten-Datei nicht vergrößern. Um Ihrem
Tabellenplatz (Tablespace) mehr hinzuzufügen, müssen Sie eine neue
Daten-Datei hinzufügen. Um das zu tun, müssen Sie Ihre MySQL-Datenbank
herunter fahren, die @file{my.cnf}-Datei editieren und eine neue Datei zu
@code{innodb_data_file_path} hinzufügen. Dann starten Sie MySQL erneut.

Momentan können Sie keine Daten-Datei aus InnoDB entfernen. Um die Größe
Ihrer Datenbank zu verringern, müssen Sie @file{mysqldump} benutzen, um
alle Ihre Tabellen zu dumpen, eine neue Datenbank erzeugen und Ihre
Tabellen in die neue Datenbank importieren.

Wenn Sie die Anzahl oder die Größe Ihrer InnoDB-Log-Dateien ändern wollen,
müssen Sie MySQL herunter fahren und sicher stellen, dass er ohne Fehler
herunter fuhr. Dann kopieren Sie die alten Log-Dateien an eine sichere
Stelle, falls etwas beim Herunterfahren schiefging und Sie die Datenbank
wiederherstellen müssen. Löschen Sie die alten Log-Dateien aus dem
Log-Datei-Verzeichnis, editieren Sie @file{my.cnf} und starten Sie MySQL
noch einmal. InnoDB meldet beim Starten, dass es neue Log-Dateien anlegt.


@node Backing up, Moving, Adding and removing, InnoDB
@c German node Datensicherung InnoDB
@subsection Datensicherung und Wiederherstellung einer InnoDB-Datenbank

Der Schlüssel zur sicheren Datenbankverwaltung sind regelmäßige
Datensicherungen. Im eine 'binäre' Sicherung Ihrer Datenbank zu machen, tun
Sie folgendes:

@itemize @bullet
@item
Fahren Sie Ihre MySQL-Datenbank herunter und stellen Sie sicher, dass dabei
keine Fehler auftraten.
@item
Kopieren Sie Ihre Daten-Dateien an eine sichere Stelle.
@item
Kopieren Sie alle InnoDB-Log-Dateien an eine sichere Stelle.
@item
Kopieren Sie Ihre @file{my.cnf} Konfigurationsdatei(en) an eine sichere
Stelle.
@item
Kopieren Sie alle @file{.frm}-Dateien für Ihre InnoDB-Tabellen an eine
sichere Stelle.
@end itemize

Momentan gibt es kein Online- oder inkrementelles Datensicherungsprogramm
für InnoDB, obwohl diese auf der TODO-Liste sind.

Zusätzlich zu den beschriebenen Binär-Datensicherungen sollten Sie
ausserdem regelmäßig Dumps Ihrer Tabellen mit @file{mysqldump} machen. Der
Grund ist, dass eine Binärdatei beschädigt sein kann, ohne dass Sie das
bemerken. Gedumpte Tabellen werden in Textdateien gespeichert, die
Menschen-lesbar und viel einfacher als binäre Datenbankdateien sind. Aus
gedumpten Dateien läßt sich Tabellenbeschädigung leichter erkennen und da
ihr Format einfacher ist, ist das Risiko ernsthafter Datenbeschädigung in
ihnen geringer.

Es ist eine gute Idee, Dumps zur gleichen Zeit zu machen wie die binäre
Datensicherung Ihrer Datenbank. Sie müssen alle Clients aus Ihrer Datenbank
ausschließen, um konsistente Schnappschüsse aller Ihrer Tabellen im Dump
zu bekommen. Danach können Sie die binäre Datensicherung machen, so dass
Sie einen konsistenten Schnappschuss Ihrer Datenbank in zwei Formaten
haben.

Um in der Lage zu sein, Ihre InnoDB-Datenbank aus den beschriebenen binären
Datensicherungen wiederherzustellen, müssen Sie Ihre MySQL-Datenbank mit
allgemeinem Loggen und angeschalteter Log-Archivierung von MySQL laufen
lassen. Mit allgemeinem Loggen ist hier der Log-Mechanismus des
MySQL-Servers gemeint, der unabhängig von den InnoDB-Logs ist.

Zum Wiederherstellen nach einem Absturz des MySQL-Serverprozesses ist es
lediglich nötig, diesen erneut zu starten. InnoDB prüft automatisch die
Log-Dateien und führt ein Roll-Forward der Datenbank bis zum aktuellen
Stand durch. InnoDB macht ein automatisches Rollback nicht abgeschlossener
(committed) Transaktionen, die zur Zeit des Absturzes anhängig waren.
Während der Wiederherstellung gibt InnoDB etwa folgendes aus:

@example
~/mysqlm/sql > mysqld
InnoDB: Database was not shut down normally.
InnoDB: Starting recovery from log files...
InnoDB: Starting log scan based on checkpoint at
InnoDB: log sequence number 0 13674004
InnoDB: Doing recovery: scanned up to log sequence number 0 13739520
InnoDB: Doing recovery: scanned up to log sequence number 0 13805056
InnoDB: Doing recovery: scanned up to log sequence number 0 13870592
InnoDB: Doing recovery: scanned up to log sequence number 0 13936128
...
InnoDB: Doing recovery: scanned up to log sequence number 0 20555264
InnoDB: Doing recovery: scanned up to log sequence number 0 20620800
InnoDB: Doing recovery: scanned up to log sequence number 0 20664692
InnoDB: 1 uncommitted transaction(s) which must be rolled back
InnoDB: Starting rollback of uncommitted transactions
InnoDB: Rolling back trx no 16745
InnoDB: Rolling back of trx no 16745 completed
InnoDB: Rollback of uncommitted transactions completed
InnoDB: Starting an apply batch of log records to the database...
InnoDB: Apply batch completed
InnoDB: Started
mysqld: ready for connections
@end example

Wenn Ihre Datenbank beschädigt wird oder Ihre Festplatte Fehler hat, müssen
Sie eine Wiederherstellung aus einer Datensicherung durchführen. Im Falle
der Beschädigung sollten Sie zunächst eine Datensicherung finden, die nicht
beschädigt ist. Machen Sie aus der Datensicherung eine Wiederherstellung
aus den allgemeinen Log-Dateien von MySQL unter Beachtung der Anleitungen
im MySQL-Handbuch.



@menu
* InnoDB checkpoints::          
@end menu

@node InnoDB checkpoints,  , Backing up, Backing up
@c German node InnoDB-Checkpoints
@subsubsection Checkpoints

InnoDB hat einen Checkpoint-Mechanismus implementiert, der sich Fuzzy
Checkpoint nennt. InnoDB schreibt veränderten Datenbankseiten aus dem
Puffer-Pool in kleinen Stapeln (Batch) auf Platte (flush), daher besteht
keine Notwendigkeit, den Puffer-Pool in einem einzelnen Stapel
zurückzuschreiben, was in der Praxis dazu führen würde, dass SQL-Statements
von Benutzern für eine Weile angehalten würden.

Bei der Reparatur nach Abstürzen sucht InnoDB nach einem Checkpoint-Label in
den Log-Dateien. Es weiß, dass alle Änderungen an der Datenbank vor dem
Label bereits im Platten-Image der Datenbank enthalten sind. InnoDB scannt
anschließend die Log-Dateien ab dem Checkpoint vorwärts und wendet die
geloggten Änderungen auf die Datenbank an.

InnoDB schreibt in zirkulärer Art in die Log-Dateien. Alle abgeschickten
(committed) Änderungen, die dazu führen, dass sich die Datenbankseiten im
Puffer-Pool vom Image auf der Platte unterscheiden, müssen in den
Log-Dateien verfügbar sein, für den Fall, dass InnoDB eine
Wiederherstellung durchführen muss. Das heißt, wenn InnoDB anfängt, eine
Log-Datei auf zirkuläre Weise wieder zu benutzen, muss es sicherstellen,
dass die Datenbankseiten-Images auf der Festplatte bereits die Änderungen
enthalten, die in der Log-Datei mitgeschrieben sind, die InnoDB benutzen
wird. Mit anderen Worten muss InnoDB einen Checkpoint machen, was oft das
Zurückschreiben auf Platte (flush) geänderter Datenbankseiten beinhaltet.

Das erklärt, warum es Festplatten-Ein- und -Ausgaben sparen kann, wenn man
die Log-Dateien sehr Groß macht. Es kann sinnvoll sein, die Gesamtgröße
der Log-Dateien so Groß wie den Puffer-Pool oder sogar noch größer zu
machen. Der Nachteil großer Log-Dateien ist, dass eine Reparatur nach
Absturz länger dauern kann, weil mehr Log-Einträge auf die Datenbank
angewendet werden müssen.


@node Moving, InnoDB transaction model, Backing up, InnoDB
@c German node Verschieben
@subsection Eine InnoDB-Datenbank auf eine andere Maschine verschieben

InnoDB-Daten- und Log-Dateien sind auf allen Plattformen binärkompatibel,
wenn das Fließkommazahlenformat auf den Maschinen dasselbe ist. Sie können
eine InnoDB-Datenbank einfach verschieben, indem Sie alle relevanten
Dateien kopieren, die im vorherigen Abschnitt über Datensicherung erwähnt
wurden. Wenn sich das Fließkommaformat auf den Maschinen unterscheidet,
sie aber keine @code{FLOAT}- oder @code{DOUBLE}-Datentypen in Ihren
Tabellen benutzt haben, ist die Prozedur dieselbe: Kopieren Sie einfach die
relevanten Dateien. Wenn die Formate unterschiedlich sind und Ihre Tabellen
Fließkomma-Daten enthalten, müssen Sie @file{mysqldump} und
@file{mysqlimport} benutzen, um diese Tabellen zu verschieben.

Ein Tipp zur Performance: Schalten Sie Auto-Commit aus, wenn Sie Daten in
Ihre Datenbank importieren (unter der Annahme, dass Ihr Tabellenplatz
(Tablespace) genug Platz für das große Rollback-Segment enthält, den die
große Import-Transaktion erzeugen wird). Machen Sie das Commit erst nach
dem Import einer ganzen Tabelle oder eines Segments einer Tabelle.


@node InnoDB transaction model, Implementation, Moving, InnoDB
@c German node InnoDB-Transaktionsmodell
@subsection InnoDB-Transaktionsmodell

Im InnoDB-Transaktionsmodell war das Ziel, die besten Eigenschaften einer
multiversionsfähigen Datenbank mit dem traditionellen Zwei-Phasen-Sperren
zu verbinden. InnoDB führt Sperren auf Zeilenebene durch und läßt Anfragen
vorgabemäßig als nicht sperrende konsistente Leseoperationen laufen, im
Stil von Oracle. Das Tabellensperren ist in InnoDB so platzsparend
gespeichert, dass keine Sperr-Eskalation benötigt wird: Typischerweise
dürfen mehrere Benutzer jede Zeile in der Datenbank oder eine beliebige
Teilmenge der Zeilen sperren, ohne dass InnoDB keinen Speicher mehr hat.

Bei InnoDB findet jede Benutzeraktivität innerhalb von Transaktionen statt.
Wenn der Auto-Commit-Modus in MySQL benutzt wird, stellt jedes
SQL-Statement eine einzelne Transaktion dar. Wenn der Auto-Commit-Modus
ausgeschaltet wird, kann man sich vorstellen, dass ein Benutzer stets eine
Transaktion offen hat. Wenn er das SQL-@code{COMMIT}- oder
@code{ROLLBACK}-Statement absetzt, beendet das die aktuelle Transaktion und
eine neue beginnt. Beide Statements heben alle InnoDB-Sperren auf, die
während der aktuellen Transaktion gesetzt wurden. Ein @code{COMMIT}
bedeutet, dass die in der aktuellen Transaktion gemachten Änderungen
permanent und sichtbar für andere Benutzer gemacht werden. Auf der anderen
Seite bricht ein @code{ROLLBACK} alle Änderungen ab, die in der aktuellen
Transaktion gemacht wurden.



@menu
* InnoDB consistent read::      
* InnoDB locking reads::        
* InnoDB Next-key locking::     
* InnoDB Locks set::            
* InnoDB Deadlock detection::   
* InnoDB Consistent read example::  
@end menu

@node InnoDB consistent read, InnoDB locking reads, InnoDB transaction model, InnoDB transaction model
@c German node Konsistentes Lesen bei InnoDB
@subsubsection Konsistentes Lesen

Konsistentes Lesen bedeutet, dass InnoDB seine Multiversionsfähigkeiten
nutzt, um einer Anfrage einen Schnappschuss der Datenbank zu einem
bestimmten Zeitpunkt zu zeigen. Die Anfrage sieht genau die Änderungen, die
von Transaktionen durchgeführt wurden, die bis zu diesem Zeitpunkt
abgeschlossen wurden (committed), und keine Änderungen, die später gemacht
wurden oder die noch nicht abgeschlossen sind. Die Ausnahme von der Regel
ist, dass die Anfrage die Änderungen sieht, die durch die Transaktion
selbst durchgeführt wurde, die die Anfrage absetzt.

Wenn eine Transaktion ihr erstes Konsistentes Lesen durchführt, weist
InnoDB den Schnappschuss oder Zeitpunkt zu, den jedes Konsistente Lesen
in derselben Transaktion benutzen wird. Im Schnappschuss sind alle
Transaktionen enthalten, die vor der Zuweisung zum Schnappschuss
abgeschlossen (committed) wurden. Daher ist Konsistentes Lesens innerhalb
derselben Transaktion auch untereinander konsistent. Sie können einen
frischeren Schnappschuss für Ihre Anfragen erhalten, indem Sie die aktuelle
Transaktion beenden (commit) und danach neue Anfragen absetzen.

Konsistentes Lesen ist der vorgabemäßige Modus, in dem InnoDB
@code{SELECT}-Statements abarbeitet. Konsistentes Lesen setzt keinerlei
Sperren auf die Tabellen, auf die es zugreift. Daher können andere Benutzer
zur selben Zeit, wie Konsistentes Lesen auf die Tabelle durchgeführt wird,
diese verändern.


@node InnoDB locking reads, InnoDB Next-key locking, InnoDB consistent read, InnoDB transaction model
@c German node Lese-Sperren bei InnoDB
@subsubsection Lesevorgänge sperren

Unter manchen Umständen ist Konsistentes Lesen nicht wünschenswert.
Angenommen, Sie wollen eine neue Zeile in die Tabelle @code{kind} einfügen
und dabei sicherstellen, dass das Kind bereits Eltern in der Tabelle
@code{eltern} hat.

Wenn Sie Konsistentes Lesen benutzen, um die Tabelle @code{eltern} zu lesen
und in der Tat die Eltern des Kindes in der Tabelle sehen, können Sie dann
sicher die Kind-Zeile zur Tabelle @code{kind} hinzufügen? Nein, denn es
kann sein, dass zwischenzeitlich jemand anderes die Eltern-Zeile aus der
Tabelle @code{eltern} gelöscht hat und Sie das nicht sehen.

Die Lösung besteht darin, das @code{SELECT} im Sperrmodus durchzuführen.
@code{LOCK IN SHARE MODE}.

@example
SELECT * FROM eltern WHERE NAME = 'Hinz' LOCK IN SHARE MODE;
@end example

Wenn Sie ein Lesen im Share-Modus durchführen, heißt das, dass die letzten
verfügbaren Daten gelesen werden und eine Shared-Modus-Sperre auf die Zeile
gesetzt wird, die gelesen wird. Wenn die letzten Daten zu einer noch nicht
abgeschlossenen Transaktion eines anderen Benutzers gehören, wird gewartet,
bis die Transaktion abgeschlossen (committed) ist. Eine Shared-Modus-Sperre
verhindert, dass andere die Zeile aktualisieren oder löschen, die gerade
gelesen wurde. Nachdem festgestellt wurde, dass die obige Anfrage die
Eltern @code{'Hinr'} zurückgibt, kann das Kind sicher zur Tabelle
@code{kind} hinzugefügt und die Transaktion abgeschlossen werden. Dieses
Beispiel zeigt, wie Sie in Ihren Applikations-Code referentielle Integrität
integrieren können.

Sehen wir uns ein weiteres Beispiel an. Wir haben ein ganzzahliges
Zählerfeld in einer Tabelle @code{kind_codes}, was benutzt wird, um jedem
Kinde, das wir der Tabelle @code{kind} hinzufügen, eine eindeutige Kennung
zuzuweisen. Es ist offensichtlich, dass Konsistentes Lesen oder
Shared-Modus-Lesen kein geeignetes Mittel ist, um den aktuellen Wert des
Zählers zu ermitteln, weil nämlich zwei Benutzer der Datenbank denselben
Wert des Zählers sehen können und wir daher einen Fehler wegen doppelter
Schlüsseleinträge erhalten, wenn wir zwei Kinder mit derselben Kennung in
die Tabelle einfügen.

In diesem Fall gibt es zwei geeignete Möglichkeiten, das Lesen und
Heraufzählen des Zählers zu implementieren:
(1) Zuerst den Zähler um eins erhöhen und erst danach lesen.
(2) Zuerst den Zähler im Sperr-Modus @code{FOR UPDATE} lesen und danach
heraufzählen:

@example
SELECT COUNTER_FIELD FROM kind_codes FOR UPDATE;
UPDATE kind_codes SET COUNTER_FIELD = COUNTER_FIELD + 1;
@end example

@code{SELECT ... FOR UPDATE} liest die letzten verfügbaren Daten und setzt
exklusive Sperren auf jede Zeile, die es liest. Daher setzt es dieselben
Sperren, die ein gesuchtes SQL-@code{UPDATE} auf die Zeilen setzen würde.


@node InnoDB Next-key locking, InnoDB Locks set, InnoDB locking reads, InnoDB transaction model
@c German node Nächsten-Schlüssel-Sperren bei InnoDB
@subsubsection Nächsten Schlüssel sperren: Wie das Phantom-Problem vermieden wird

Beim Sperren auf Zeilenebene benutzt InnoDB einen Algorithmus, der
Nächsten-Schlüssel-Sperren genannt wird. InnoDB führt das Sperren auf
Zeilenebene so durch, dass es beim Suchen oder Scannen eines Indexes auf
eine Tabelle gemeinsam genutzte (shared) oder exklusive Sperren auf die
Index-Datensätze setzt, die es findet. Daher werden die Sperren auf
Zeilenebene genauer Index-Datensatz-Sperren genannt.

Die Sperren, die InnoDB auf Index-Datensätze setzt, betreffen auch die
'Lücke' vor diesem Index-Datensatz. Wenn ein Benutzer eine gemeinsam
benutzte (shared) oder exklusive Sperre auf den Datensatz R in einem Index
hat, kann ein anderen Benutzer keinen Datensatz direkt vor R (in der
Index-Reihenfolge) einfügen. Dieses Sperren von Lücken wird durchgeführt,
um das so genannte Phantom-Problem zu vermeiden. Angenommen, man will alle
Kinder aus der Tabelle @code{kind} lesen und sperren, die eine Kennung
größer 100 haben, und irgend ein Feld in der ausgewählten Zeile
aktualisieren:

@example
SELECT * FROM kind WHERE ID > 100 FOR UPDATE;
@end example

Angenommen, es gibt einen Index auf der Tabelle @code{kind} auf der Spalte
@code{ID}. Unsere Anfrage scannt diesen Index ab dem ersten Datensatz, bei
dem @code{ID} größer als 100 ist. Wenn jetzt die auf den Index-Datensatz
gesetzten Sperren nicht Einfügeoperationen sperren würden, die in die
Lücken ausgeführt würden, könnte zwischenzeitlich ein neues Kind in die
Tabelle eingefügt werden. Wenn jetzt unsere Transaktion noch einmal
folgendes ausführen würde:

@example
SELECT * FROM kind WHERE ID > 100 FOR UPDATE;
@end example

Sehen wir ein neues Kind in der Ergebnismenge, die die Anfrage zurückgibt.
Das verstößt gegen das Isolationsprinzip von Transaktionen: Eine
Transaktion sollte in der Lage sein, so abzulaufen, dass die Daten, die sie
gelesen hat, sich nicht während der Transaktion ändern. Wenn wir einen Satz
von Zeilen als Daten-Posten betrachten, würde das neue 'Phantom'-Kind
dieses Isolationsprinzip durchbrechen.

Wenn InnoDB einen Index scannt, kann es auch die Lücke nach dem letzten
Datensatz im Index sperren. Genau das passiert im vorherigen Beispiel: Die
Sperren, die von InnoDB gesetzt werden, verhindert jedes Einfügen in die
Tabelle an Stellen, wo @code{ID} größer als 100 ist.

Sie können Nächsten-Schlüssel-Sperren dazu benutzen, eine
Eindeutigkeitsprüfung in Ihre Applikation zu implementieren: Wenn Sie Ihre
Daten im Share-Modus lesen und kein Duplikat für eine Zeile sehen, die Sie
einfügen werden, können Sie Ihre Zeile sicher einfügen und wissen, dass das
Nächsten-Schlüssel-Sperren verhindern wird, dass zwischenzeitlich jemand
eine Duplikatzeile Ihrer Zeile einfügt. Daher gestattet Ihnen das
Nächsten-Schlüssel-Sperren, die Nicht-Existenz von irgend etwas in Ihrer
Tabelle zu 'sperren'.

@node InnoDB Locks set, InnoDB Deadlock detection, InnoDB Next-key locking, InnoDB transaction model
@c German node Bei InnoDB gesetzte Sperren
@subsubsection Sperren, die in InnoDB durch unterschiedliche SQL-Statements gesetzt werden

@itemize @bullet
@item
@code{SELECT ... FROM ...} : Das ist Konsistentes Lesen, es wird ein
Schnappschuss einer Datenbank gelesen und es werden keine Sperren gesetzt.
@item
@code{SELECT ... FROM ... LOCK IN SHARE MODE} : setzt gemeinsam genutztes
(shared) Nächsten-Schlüssel-Sperren auf alle Index-Datensätze, die beim
Lesen gefunden werden.
@item
@code{SELECT ... FROM ... FOR UPDATE} : setzt exklusives
Nächsten-Schlüssel-Sperren auf alle Index-Datensätze, die beim Lesen
gefunden werden.
@item
@code{INSERT INTO ... VALUES (...)} : setzt eine exklusive Sperre auf die
eingefügte Zeile. Beachten Sie, dass diese Sperre kein
Nächsten-Schlüssel-Sperren ist und andere Benutzer nicht davon abhält,
etwas in die Lücke vor der eingefügten Zeile einzufügen. Wenn ein Fehler
wegen doppelter Schlüsseleinträge auftritt, setzt dieser Befehl eine
gemeinsam genutzte (shared) Sperre auf den doppelten (Duplikat)
Index-Datensatz.
@item
@code{INSERT INTO T SELECT ... FROM S WHERE ...} setzt eine exklusive
Sperre (kein Nächsten-Schlüssel-Sperren) auf jede Zeile, die in @code{T}
eingefügt wurde. Sucht nach @code{S} in Form von Konsistentem Lesen, aber
setzt Nächsten-Schlüssel-Sperren auf @code{S}, wenn bei MySQL das Loggen
angeschaltet ist. InnoDB muss in letzterem Fall Sperren setzen, weil bei
einer Roll-Forward-Wiederherstellung aus einer Datensicherung jedes
SQL-Statement auf genau dieselbe Weise ausgeführt werden muss, wie es
ursprünglich ausgeführt wurde.
@item
@code{CREATE TABLE ... SELECT ...} führt @code{SELECT} als Konsistentes
Lesen oder mit gemeinsam genutzten (shared) Sperren aus, wie im vorherigen
Punkt.
@item
@code{REPLACE} wird wie Einfügen ausgeführt, wenn es keine Kollision auf
einem eindeutigen Schlüssel gibt. Ansonsten wird ein exklusives
Nächsten-Schlüssel-Sperren auf die Reihe gesetzt, die aktualisiert werden
muss.
@item
@code{UPDATE ... SET ... WHERE ...} setzt ein exklusives
Nächsten-Schlüssel-Sperren auf jeden Datensatz, der beim Suchen gefunden
wird.
@item
@code{DELETE FROM ... WHERE ...} setzt ein exklusives
Nächsten-Schlüssel-Sperren auf jeden Datensatz, der beim Suchen gefunden
wird.
@item
Wenn auf der Tabelle eine @code{FOREIGN KEY}-Beschränkung definiert ist,
setzt jedes Einfügen, Aktualisieren oder Löschen, was die Überprüfung der
Beschränkungsbedingung erfordert, gemeinsam genutzte (shared) Sperren auf
Datensatzebene auf die Datensätze, die bei der Überprüfung der Beschränkung
betrachtet werden. Auch im Falle, dass die Beschränkung fehlschlägt, setzt
InnoDB diese Sperren.
@item
@code{LOCK TABLES ... } : setzt Tabellensperren. In der Implementation
setzt die MySQL-Ebene des Codes diese Sperren. Die automatische
Blockierungserkennung von InnoDB kann keine Blockierungen bemerken, bei
denen solche Tabellensperren involviert sind, siehe nächster Abschnitt
weiter unten. Sehen Sie auch im Abschnitt 13 ('InnoDB-Einschränkungen')
wegen folgendem nach: Weil MySQL keine Sperren auf Zeilenebene erkennt, ist
es möglich, dass Sie eine Sperre auf eine Tabelle erhalten, auf der ein
anderer Benutzer momentan Sperren auf Zeilenebene hat. Das gefährdet
allerdings nicht die Transaktionsintegrität.
@end itemize


@node InnoDB Deadlock detection, InnoDB Consistent read example, InnoDB Locks set, InnoDB transaction model
@c German node Blockierungserkennung bei InnoDB
@subsubsection Blockierungserkennung und Rollback

InnoDB erkennt automatisch eine Blockierung von Transaktionen und rollt die
Transaktion zurück, deren Sperranforderung diejenige war, die die
Blockierung aufbaute, also einen Kreis im Warte-Diagramm von Transaktionen.
InnoDB kann keine Blockierungen erkennen, bei denen eine Sperre im Spiel
ist, die durch ein MySQL-@code{LOCK TABLES}-Statement verursacht wurde,
oder wenn eine Sperre durch einen anderen Tabellen-Handler als InnoDB
gesetzt wurde. Solche Situationen müssen Sie mit
@code{innodb_lock_wait_timeout}, das in @file{my.cnf} gesetzt wird.

Wenn InnoDB ein komplettes Rollback einer Transaktion durchführt, werden
alle Sperren der Transaktion aufgehoben. Wenn jedoch nur ein einzelnes
SQL-Statement als Ergebnis eines Fehlers zurückgerollt wird, können einige
der Sperren, die durch das SQL-Statement gesetzt wurde, verbleiben. Das
liegt daran, dass InnoDB Zeilensperren in einem Format speichert, die ihm
unmöglich machen, im Nachhinein zu erkennen, welche Sperre durch welches
SQL-Statement gesetzt wurde.

@node InnoDB Consistent read example,  , InnoDB Deadlock detection, InnoDB transaction model
@c German node Konsistentes Lesen bei InnoDB im Beispiel
@subsubsection Ein Beispiel, wie konsistentes Lesen bei InnoDB funktioniert

Wenn Sie ein Konsistentes Lesen ausführen, also ein gewöhnliches
@code{SELECT}-Statement, gibt InnoDB Ihrer Transaktion einen Zeitpunkt
(Timepoint), gemäß dem Ihre Anfrage die Datenbank sieht. Wenn daher
Transaktion B eine Zeile löscht und das wirksam wird (commit), nachdem Ihr
Zeitpunkt zugewiesen wurde, werden Sie die Zeile nicht als gelöscht sehen.
Gleiches gilt für Einfüge- und Aktualisierungsoperationen.

Sie können Ihren Zeitpunkt 'vorstellen', indem Sie Ihre Transaktion
abschicken (commit) und dann ein weiteres @code{SELECT} ausführen.

Das nennt sich Multiversioned Concurrency Control (multiversionierte
Gleichzeitigkeitskontrolle):

@example
                  Benutzer A             Benutzer B

              set autocommit=0;      set autocommit=0;
zeit
|             SELECT * FROM t;
|             empty set
|                                    INSERT INTO t VALUES (1, 2);
|
v             SELECT * FROM t;
              empty set
                                     COMMIT;

              SELECT * FROM t;
              empty set;

              COMMIT;

              SELECT * FROM t;
              ---------------------
              |    1    |    2    |
              ---------------------
@end example

Daher sieht Benutzer A die durch B eingefügte Zeile erst, wenn B das
Einfügen und A seine eigene Transaktion abgeschickt hat (commit), so dass
der Zeitpunkt hinter das Commit von B 'vorgestellt' ist.

Wenn Sie den 'frischsten' Zustand der Datenbank sehen wollen, sollten Sie
ein sperrendes Lesen (Locking Read) benutzen:

@example
SELECT * FROM t LOCK IN SHARE MODE;
@end example


@subsection Tipps zur Performance-Steigerung

@strong{1.}
Wenn das Unix-@file{top} oder der Windows-@file{Task-Manager} zeigen, dass
die CPU-Auslastung weniger als 70% beträgt, ist Ihre Auslastung
wahrscheinlich Platten-gebunden. Das kann daran liegen, dass Sie zu viele
Transaktionen abschicken (commit) oder dass der Puffer-Pool zu klein ist.
Dann kann es helfen, den Puffer-Pool zu vergrößern. Setzen Sie ihn aber
nicht höher als 80% des physikalischen Arbeitsspeichers.

@strong{2.}
Packen Sie mehrere Änderungen in eine Transaktion. InnoDB muss das Log
jedes Mal auf Platte zurückschreiben (flush), wenn eine Transaktion
abgeschickt wird (commit), wenn diese Transaktion irgend welche Änderungen
an der Datenbank vorgenommen hat. Weil die Rotationsgeschwindigkeit einer
Platte typischerweise höchsten 167 Umdrehungen pro Sekunde beträgt,
beschränkt das die Anzahl von Commits auf eben diese Zahl pro Sekunde, wenn
die Festplatte nicht das Betriebssystem täuscht.

@strong{3.}
Wenn Sie es sich leisten können, einige der zuletzt abgeschickten
(committed) Transaktionen zu verlieren, können Sie den
@file{my.cnf}-Parameter @code{innodb_flush_log_at_trx_commit} auf 0 setzen.
InnoDB versucht dann trotzdem, das Log einmal pro Sekunde auf Platte
zurückzuschreiben (flush), doch dieses Zurückschreiben ist nicht
garantiert.

@strong{4.}
Machen Sie Ihre Log-Dateien Groß, selbst so Groß wie den Puffer-Pool.
Wenn InnoDB seine Log-Dateien vollgeschrieben hat, muss es die veränderten
Inhalte des Puffer-Pools in einem Checkpoint auf Platte schreiben. Kleine
Log-Dateien verursachen daher unnötige Festplatten-Schreibzugriffe. Der
Nachteil großer Log-Dateien liegt darin, dass die Wiederherstellungszeit
länger wird.

@strong{5.}
Ausserdem sollte der Log-Puffer recht Groß sein, sagen wir 8 MB.

@strong{6.} (Relevant from 3.23.39 up.)
In einigen Versionen von Linux und Unix ist das Zurückschreiben von Dateien
auf Platte (flush) mit dem Unix-@code{fdatasync} und anderen ähnlichen
Methoden überraschend langsam. InnoDB benutzt vorgabemäßig die
@code{fdatasync}-Funktion. Wenn Sie mit der Datenbank-Schreib-Performance
nicht zufrieden sind, können Sie versuchen, die @code{innodb_flush_method}
in @file{my.cnf} auf @code{O_DSYNC} zu setzen, obwohl O_DSYNC auf den
meisten Systemen langsamer zu sein scheint.

@strong{7.} Wenn Sie Daten in InnoDB importieren, stellen Sie sicher, dass
MySQL @code{autocommit=1} nicht angeschaltet hat, denn dann benötigt jedes
Einfügen ein Zurückschreiben des Logs auf Platte (flush). Setzen Sie vor
Ihre SQL-Importdatei die Zeile

@example
set autocommit=0;
@end example

und danach

@example
commit;
@end example

Wenn Sie die @file{mysqldump}-Option @code{--opt} benutzen, erhalten Sie
Dump-Dateien, die sich sehr schnell auch in eine InnoDB-Tabelle importieren
lassen, selbst ohne sie in die oben erwähnten @code{set autocommit=0; ...
commit;}-Wrapper zu verpacken.

@strong{8.}
Hüten Sie sich vor großen Rollbacks beim Einfügen von Massendaten: InnoDB
benutzt den Einfüge-Puffer, um beim Einfügen Festplatten-Ein- und -Ausgaben
zu sparen, doch beim entsprechenden Rollback wird kein solcher Mechanismus
benutzt. Ein Festplatten-gebundenes Rollback kann die 30-fache Zeit des
entsprechenden Einfügevorgangs in Anspruch nehmen. Es hilft nicht, den
Datenbankprozess zu killen, weil der Rollback erneut starten wird, wenn die
Datenbank hochfährt. Die einzige Möglichkeit, ein aus dem Ruder gelaufenes
Rollback loszuwerden, besteht darin, den Puffer-Pool zu erhöhen, so dass
das Rollback CPU-gebunden wird und damit schnell läuft, oder indem die
gesamte InnoDB-Datenbank gelöscht wird.

@strong{9.}
Seien Sie auch vor anderen großen Festplatten-gebundenen Operationen auf
der Hut. Benutzen Sie @code{DROP TABLE} oder @code{TRUNCATE} (ab
MySQL-4.0), um eine Tabelle zu löschen, nicht @code{DELETE FROM tabelle}.

@strong{10.}
Benutzen Sie das mehrzeilige @code{INSERT}, um den Kommunikations-Overhead
zwischen Client und Server zu verringern, wenn Sie viele Zeilen einfügen
müssen:

@example
INSERT INTO tabelle VALUES (1, 2), (5, 5);
@end example

Dieser Tipp gilt natürlich für jeden Tabellentyp, nicht nur für InnoDB.

@subsubsection Der InnoDB-Monitor

Ab Version 3.23.41 beinhaltet InnoDB den InnoDB-Monitor, der Informationen
über den internen Zustand von InnoDB ausgibt. Wenn er angeschaltet ist,
veranlasst der InnoDB-Monitor den MySQL-Server @file{mysqld}, etwa alle 15
Sekunden Daten an die Standardausgabe auszugeben (Hinweis: der MySQL-Client
gibt nichts aus). Diese Daten sind nützlich, um die Performance zu tunen.
Unter Windows müssen Sie @code{mysqld-max} von einer DOS-Kommandozeile aus
mit @code{--standalone --console} starten, um die Ausgabe auf das
DOS-Fenster umzuleiten.

Es gibt einen separaten @code{innodb_lock_monitor}, der dieselben
Informationen ausgibt wie @code{innodb_monitor}, aber zusätzlich
Informationen über Sperren, die durch jede Transaktion gesetzt werden.

Die ausgegebene Information enthält Daten über:
@itemize @bullet
@item
Sperren, die auf eine Transaktion warten,
@item
Semaphore, die auf Threads warten,
@item
anhängige Datei-Ein- und -Ausgabeanforderungen,
@item
Puffer-Pool-Statistiken und
@item
Bereinigungs- (purge) und Einfüge-Puffer-Vermengungs- (merge) Aktivität des
Haupt-Threads von InnoDB.
@end itemize

Sie können den InnoDB-Monitor mit folgendem SQL-Befehl starten:

@example
CREATE TABLE innodb_monitor(a int) type = innodb;
@end example

Und ihn mit folgendem Befehl anhalten:

@example
DROP TABLE innodb_monitor;
@end example

Die @code{CREATE TABLE}-Syntax ist nur eine Möglichkeit, einen Befehl durch
den MySQL-SQL-Parser an die InnoDB-Engine durchzureichen. Wenn Sie die
Datenbank herunter fahren, während der Monitor läuft, und Sie den Monitor
erneut starten wollen, müssen Sie die Tabelle löschen, bevor Sie ein
erneutes @code{CREATE TABLE} absetzen können, um den Monitor zu starten.
Diese Syntax wird sich in zukünftigen Releases möglicherweise ändern.


Beispiel für die Ausgabe des InnoDB-Monitors:

@example
================================
010809 18:45:06 INNODB MONITOR OUTPUT
================================
--------------------------
LOCKS HELD BY transactions
--------------------------
LOCK INFO:
Number of locks in the record hash table 1294
LOCKS FOR TRANSACTION ID 0 579342744
TABLE LOCK table test/tabelle trx id 0 582333343 lock_mode IX

RECORD LOCKS space id 0 page no 12758 n bits 104 table test/tabelle index
PRIMARY trx id 0 582333343 lock_mode X
Record lock, heap no 2 PHYSICAL RECORD: n_fields 74; 1-byte offs FALSE;
info bits 0
 0: len 4; hex 0001a801; asc ;; 1: len 6; hex 000022b5b39f; asc ";; 2: len 7;
hex 000002001e03ec; asc ;; 3: len 4; hex 00000001;
...
-----------------------------------------------
CURRENT SEMAPHORES RESERVED AND SEMAPHORE WAITS
-----------------------------------------------
SYNC INFO:
Sorry, cannot give mutex list info in non-debug version!
Sorry, cannot give rw-lock list info in non-debug version!
-----------------------------------------------------
SYNC ARRAY INFO: reservation count 6041054, signal count 2913432
4a239430 waited for by thread 49627477 op. S-LOCK file NOT KNOWN line 0 
Mut ex 0 sp 5530989 r 62038708 sys 2155035; rws 0 8257574 8025336; rwx 0 1121090 1848344
-----------------------------------------------------
CURRENT PENDING FILE I/O'S
--------------------------
Pending normal aio reads:
Reserved slot, messages 40157658 4a4a40b8
Reserved slot, messages 40157658 4a477e28
...
Reserved slot, messages 40157658 4a4424a8
Reserved slot, messages 40157658 4a39ea38
Total of 36 reserved aio slots
Pending aio writes:
Total of 0 reserved aio slots
Pending insert buffer aio reads:
Total of 0 reserved aio slots
Pending log writes or reads:
Reserved slot, messages 40158c98 40157f98
Total of 1 reserved aio slots
Pending synchronous reads or writes:
Total of 0 reserved aio slots
-----------
BUFFER POOL
-----------
LRU list length 8034 
Free list length 0 
Flush list length 999 
Buffer pool size in pages 8192
Pending reads 39 
Pending writes: LRU 0, flush list 0, single page 0
Pages read 31383918, created 51310, written 2985115
----------------------------
END OF INNODB MONITOR OUTPUT
============================
010809 18:45:22 InnoDB starts purge
010809 18:45:22 InnoDB purged 0 pages
@end example

Einige Anmerkungen zur Ausgabe:

@itemize @bullet
@item
Wenn der Abschnitt @code{LOCKS HELD BY transactions} warten auf Sperren
berichtet, kann es sein, dass Ihre Applikation Sperr-Konflikte hat. Die
Ausgabe kann auch helfen, Gründe für Transaktions-Blockierungen
aufzuspüren.
@item
Der Abschnitt @code{SYNC INFO} berichtet reservierte Semaphore, wenn Sie
InnoDB mit @code{UNIV_SYNC_DEBUG} kompilieren, definiert in @file{univ.i}.
@item
Der Abschnitt @code{SYNC ARRAY INFO} berichtet Threads, die auf ein
Semaphor warten, und Statistiken, wie viele Male Threads ein Spin oder ein
Warten auf einem Mutex oder einem Lese-/Schreibe-Sperr-Semaphor benötigten.
Eine große Anzahl auf Semaphore wartender Threads kann ein Ergebnis von
Festplatten-Ein- und -Ausgaben oder Konfliktproblemen innerhalb von InnoDB
sein. Konflikte können durch starke Parallelen von Anfragen oder durch
Probleme des Betriebssystems beim Thread Scheduling hervorgerufen werden.
@item
Der Abschnitt @code{CURRENT PENDING FILE I/O'S} listet anhängige Datei-Ein-
und -Ausgabeanforderungen auf. Eine große Anzahl davon zeigt an, dass die
Auslastung Festplatten-Ein- und -Ausgabe-gebunden ist.
@item
Der Abschnitt @code{BUFFER POOL} gibt statistische Informationen über
gelesene und geschriebene Seiten. Aus diesen Zahlen können Sie errechnen,
wie viele Daten-Datei-Ein- und Ausgaben Ihre Anfragen aktuell durchführen.
@end itemize

@node Implementation, Table and index, InnoDB transaction model, InnoDB
@c German node Implementation
@subsection Implementation des Multiversionings

Weil InnoDB eine multiversionierte Datenbank ist, muss es Informationen
über alte Versionen von Zeilen im Tabellenplatz (Tablespace) aufbewahren.
Diese Informationen werden in einer Datenstruktur gespeichert, die wir in
Anlehnung an eine analoge Struktur in Oracle Rollback-Segment nennen.

InnoDB fügt jeder Zeile, die in der Datenbank gespeichert wird, intern zwei
Felder hinzu. Ein 6 Byte großes Feld enthält den
Transaktions-Identifikator der letzten Transaktion, die die Zeile eingefügt
oder aktualisiert hat. Ein Löschen wir intern als eine Aktualisierung
behandelt, wobei ein spezielles Bit in die Zeile eingefügt wird, um sie als
gelöscht zu markieren. Jede Zeile enthält ausserdem ein 7 Byte großes
Feld, das Roll-Zeiger genannt wird. Der Roll-Zeiger zeigt auf einen
Rückgängig-Log-Datensatz, der in das Rollback-Segment geschrieben wird.
Wenn die Zeile aktualisiert wurde, enthält der Rückgängig-Log-Datensatz die
Informationen, die notwendig sind, um den Inhalt der Zeile wieder
herzustellen, bevor sie aktualisiert wurde.

InnoDB benutzt die Informationen im Rollback-Segment, um die
Rückgängig-Operationen durchzuführen, die bei einem Transaktions-Rollback
notwendig sind. Diese Informationen benutzt es auch dafür, um frühere
Informationen einer Zeile beim Konsistenten Lesen aufzubauen.

Rückgängig-Logs im Rollback-Segment lassen sich in Logs für Einfügen und
für Aktualisieren unterteilen. Einfüge-Rückgängig-Logs werden nur für
Transaktions-Rollbacks benötigt und können verworfen werden, sobald die
Transaktion abgeschickt ist (commit). Aktualisierungs-Rückgängig-Logs
werden auch für Konsistentes Lesens benutzt und können daher erst verworfen
werden, wenn keine Transaktion mehr vorhanden ist, für die InnoDB einen
Schnappschuss zugewiesen hat, dessen Informationen beim Konsistenten Lesen
benötigt werden könnten, um daraus eine frühere Version der Datenbank-Zeile
aufzubauen.

Sie müssen daran denken, Ihre Transaktionen regelmäßig abzuschicken
(commit), auch die Transaktionen, die nur Konsistentes Lesens ausführen.
Ansonsten kann InnoDB Daten aus dem Aktualisierungs-Rückgängig-Log nicht
verwerfen und das Rollback-Segment könnte zu Groß werden und Ihren
Tabellenplatz (Tablespace) komplett füllen.

Die physikalische Größe eines Rückgängig-Log-Datensatzes im
Rollback-Segment ist typischerweise kleiner als die entsprechende
eingefügte oder aktualisierte Zeile. Sie können diese Informationen
benutzen, um den Platzbedarf für Ihr Rollback-Segment zu berechnen.

In diesem multiversionierten Schema wird eine Zeile nicht unmittelbar
physikalisch aus der Datenbank entfernt, wenn Sie sie mit einem
SQL-Statement löschen. Erst wenn InnoDB den Datensatz des
Aktualisierungs-Rückgängig-Logs löschen kann, der für das Löschen
geschrieben wurde, kann es die entsprechende Zeile und ihre
Index-Datensätze auch physikalisch aus der Datenbank entfernen. Diese
Entfernungsoperation wird Purge genannt und ist recht schnell, wobei sie
überschlägig dieselbe Zeit benötigt wie das SQL-Statement, das das Löschen
ausführte.


@node Table and index, File space management, Implementation, InnoDB
@c German node Tabelle und Index
@subsection Tabellen- und Index-Strukturen

MySQL speichert seine Daten-Wörterbuch-Informationen über Tabellen in
@file{.frm}-Dateien in den Datenbank-Verzeichnissen. Jedoch hat auch jede
Tabelle vom Typ InnoDB ihren eigenen Eintrag, in InnoDB-internen
Daten-Wörterbüchern innerhalb des Tabellenplatzes (Tablespace). Wenn MySQL
eine Tabelle oder Datenbank löscht, muss er sowohl eine oder mehrere
@file{.frm}-Datei(en) als auch die entsprechenden Einträge im
InnoDB-Daten-Wörterbuch löschen. Das ist der Grund, warum Sie
InnoDB-Tabellen nicht einfach zwischen Datenbanken verschieben können,
indem Sie die @file{.frm}-Dateien verschieben und warum @code{DROP
DATABASE} bei InnoDB-Tabellen in MySQL-Versionen bis 3.23.43 nicht
funktionierte.

Jede InnoDB-Tabelle hat einen speziellen Index, der Cluster-Index genannt
wird, in dem die Daten der Zeilen gespeichert sind. Wenn Sie auf Ihre
Tabelle einen @code{PRIMARY KEY} definieren, ist der Index des
Primärschlüssels der Cluster-Index.

Wenn Sie für Ihre Tabelle keinen Primärschlüssel definieren, erzeugt InnoDB
intern einen Cluster-Index, bei dem die Zeilen nach der Zeilen-Kennung (ID)
geordnet sind, die InnoDB Zeilen in einer solchen Tabelle zuweist. Die
Zeilen-Kennung ist ein 6 Byte großes Feld, das monoton erhöht wird, wenn
neue Zeilen eingefügt werden. Daher liegen nach der Zeilen-Kennung
geordnete Zeile physikalisch in der Einfüge-Reihenfolge vor.

Der Zugriff auf eine Zeile über den Cluster-Index ist schnell, weil die
Zeilendaten auf derselben Seite sind, auf die die Index-Suche führt. In
vielen Datenbanken werden die Daten traditionell auf einer anderen Seite
als derjenigen, wo sich der Index-Datensatz befindet, gespeichert. Wenn die
Tabelle Groß ist, spart die Cluster-Index-Architektur im Vergleich zur
traditionellen Lösung auf Festplatten-Ein- und -Ausgaben.

In InnoDB enthalten die Datensätze in Nicht-Cluster-Indexen (die wir auch
sekundäre Indexe nennen) den Primärschlüsselwert für die Zeile. InnoDB
benutzt diesen Primärschlüsselwert, um vom Cluster-Index aus nach der Zeile
zu suchen. Beachten Sie, dass die sekundären Indexe mehr Platz benötigen,
wenn der Primärschlüssel lang ist.



@menu
* InnoDB physical structure::   
* InnoDB Insert buffering::     
* InnoDB Adaptive hash::        
* InnoDB Physical record::      
@end menu

@node InnoDB physical structure, InnoDB Insert buffering, Table and index, Table and index
@c German node Physikalische Struktur von InnoDB
@subsubsection Physikalische Struktur eines Indexes

Alle Indexe in InnoDB sind B-Bäume, in denen die Index-Datensätze in den
Blätter-Seiten des Baums gespeichert sind. Die vorgabemäßige Größe einer
Index-Seite ist 16 KB. Wenn neue Datensätze eingefügt werden, versucht
InnoDB, 1/16 der Seite für zukünftige Einfügungen und Aktualisierungen des
Index-Datensatzes freizuhalten.

Wenn Index-Datensätze in sequentieller (aufsteigender oder absteigender)
Reihenfolge eingefügt werden, sind die resultierenden Index-Seiten ungefähr
zu 15/16 gefüllt. Wenn der Füllfaktor einer Index-Seite unter 1/12 fällt,
versucht InnoDB, den Index-Baum zusammenzuziehen, um die Seite
freizugeben.


@node InnoDB Insert buffering, InnoDB Adaptive hash, InnoDB physical structure, Table and index
@c German node Einfügepuffer von InnoDB
@subsubsection Einfügepufferung

Häufig wird der Primärschlüssel in Datenbank-Applikationen als eindeutiger
Identifizierer benutzt und neue Zeilen in aufsteigender Reihenfolge des
Primärschlüssels eingefügt. Daher erfordern Einfügungen in den
Cluster-Index keine wahlfreien (random) Lesezugriffe auf die Platte.

Sekundäre Indexe auf der anderen Seite sind üblicherweise nicht eindeutig
und Einfügungen in sekundäre Indexe erfolgen in einer relativ wahlfreien
Reihenfolge. Wenn InnoDB keinen speziellen Mechanismus hierfür benutzen
würde, würden diese viele wahlfreie Festplatten-Ein- und -Ausgaben
verursachen.

Wenn ein Index-Datensatz in einen nicht eindeutigen sekundären Index
eingefügt werden soll, prüft InnoDB, ob die sekundäre Index-Seite bereits
im Puffer-Pool ist. Wenn das der Fall ist, führt InnoDB das Einfügen direkt
in die Index-Seite durch. Wenn die Index-Seite aber nicht im Puffer-Pool
gefunden wird, fügt InnoDB den Datensatz in eine spezielle
Einfüge-Puffer-Struktur ein. Der Einfüge-Puffer wird so klein gehalten,
dass er komplett in den Puffer-Pool passt, so dass Einfügungen sehr schnell
durchgeführt werden können.

Der Einfüge-Puffer wird periodisch mit den sekundären Index-Bäumen in der
Datenbank vermengt. Oft können mehrere Einfügeoperationen auf derselben
Seite im Index-Baum zusammengefasst werden, so dass Festplatten-Ein- und
-Ausgaben eingespart werden. Messungen ergaben, dass der Einfüge-Puffer
Einfügungen in eine Tabelle bis zu 15 mal schneller machen kann.


@node InnoDB Adaptive hash, InnoDB Physical record, InnoDB Insert buffering, Table and index
@c German node Anpassungsfähiger Hash in InnoDB
@subsubsection Anpassungsfähige Hash-Indexe

Wenn eine Datenbank fast komplette in den Hauptspeicher passt, können
Anfragen am schnellsten unter Verwendung von Hash-Indexen ausgeführt
werden. InnoDB hat einen automatischen Mechanismus, der Index-Suchen
beobachtet, die auf den Indexen durchgeführt werden, die für eine Tabelle
definiert wurden. Wenn InnoDB bemerkt, dass Anfragen vom Aufbauen eines
Hash-Indexes profitieren könnten, wird ein solcher Index automatisch
aufgebaut.

Beachten Sie aber, dass der Hash-Index immer auf der Grundlage eines
bestehenden B-Baum-Indexes auf die Tabelle aufgebaut wird. InnoDB kann
einen Hash-Index auf einem Präfix beliebiger Länge des Schlüssels aufbauen,
der für den B-Baum definiert wurde, abhängig vom Suchmuster, das InnoDB auf
dem Index-Baum beobachtet. Ein Hash-Index kann partiell sein: Es ist nicht
erforderlich, dass der gesamte Index-Baum im Puffer-Pool
zwischengespeichert ist. InnoDB baut Hash-Indexe bei Bedarf automatisch für
die Index-Seiten auf, auf die oft zugegriffen wird.

In gewisser Hinsicht kommt InnoDB durch den anpassungsfähigen
Hash-Index-Mechanismus (wobei sich InnoDB üppig verfügbarem Hauptspeicher
anpasst) der Architektur von Hauptspeicher-Datenbanken nahe.


@node InnoDB Physical record,  , InnoDB Adaptive hash, Table and index
@c German node Physikalischer Datensatz in InnoDB
@subsubsection Physikalische Datensatzstruktur

@itemize @bullet
@item
Jeder Index-Datensatz in InnoDB enthält einen Header von 6 Bytes. Der
Header wird benutzt, um nachfolgende Datensätze zu verknüpfen, sowie beim
Sperren auf Zeilenebene.
@item
Datensätze im Cluster-Index enthalten Felder für alle benutzerdefinierten
Spalten. Zusätzlich gibt es ein 6 Byte großes Feld für die
Transaktions-Kennung und ein 7 Byte großes Feld für den Roll-Zeiger.
@item
Wenn der Benutzer keinen Primärschlüssel für eine Tabelle definiert hat,
enthält jeder Cluster-Index-Datensatz zusätzlich ein 6 Byte großes
Zeilenkennungsfeld.
@item
Jeder sekundäre Index-Datensatz enthält auch alle Felder, die für den
Cluster-Index-Schlüssel definiert wurden.
@item
Ein Datensatz enthält auch einen Zeiger zu jedem Feld des Datensatzes. Wenn
die Gesamtlänge des Feldes in einem Datensatz kleiner als 128 Bytes ist,
ist der Zeiger 1 Byte lang, ansonsten 2 Bytes.
@end itemize

@subsubsection Wie eine Auto-Increment-Spalte in InnoDB funktioniert

Wenn der Benutzer nach einem Datenbankstart zuerst einen Datensatz in eine
Tabelle @code{T} einfügt, in der eine Auto-Increment-Spalte definiert
wurde, und er keinen expliziten Wert für die Spalte angibt, führt InnoDB
@code{SELECT MAX(auto-inc-column) FROM T} aus und weist den um 1
hochgezählten Wert der Spalte und dem Auto-Increment-Zähler der Tabelle zu.
Wir sagen dazu, dass der Auto-Increment-Zähler für Tabelle @code{T}
initialisiert wurde.

InnoDB führt dieselbe Prozedur der Initialisierung des
Auto-Increment-Zählers für eine frisch erzeugte Tabelle durch.

Wenn Sie für die Auto-Increment-Spalte einen Wert von 0 angeben, beachten
Sie, dass InnoDB die Zeile so behandelt, als hätten Sie den Wert nicht
angegeben.

Wenn nach der Initialisierung des Auto-Increment-Zählers der Benutzer eine
Zeile eingibt, in der er explizit den Spaltenwert angibt, und dieser
größer als der aktuelle Zählerwert ist, wird der Zähler auf den
angegebenen Spaltenwert gesetzt. Wenn der Benutzer nicht explizit einen
Wert angibt, zählt InnoDB den Zähler um 1 hoch und weist der Spalte diesen
neuen Wert zu.

Der Auto-Increment-Mechanismus umgeht beim Zuweisen von Werten vom Zähler
Sperren und Transaktionshandhabung. Daher können Lücken in der
Nummernfolge entstehen, wenn Sie Transaktionen zurückrollen (Rollback), die
Nummern vom Zähler erhalten haben.

Das Verhalten von Auto-Increment ist für die Fälle undefiniert, in denen
ein Benutzer der Spalte einen negativen Wert gibt oder wenn der Wert
größer als die größte Ganzzahl wird, die im festgelegten Ganzzahl-Typ
gespeichert werden kann.


@node File space management, Error handling, Table and index, InnoDB
@c German node Verwaltung von Datei-Speicherplatz
@subsection Verwaltung von Datei-Speicherplatz und Festplatten-Eingaben / -Ausgaben



@menu
* InnoDB Disk I/O::             
* InnoDB File space::           
* InnoDB File Defragmenting::   
@end menu

@node InnoDB Disk I/O, InnoDB File space, File space management, File space management
@c German node Festplatten-Ein- und -Ausgaben bei InnoDB
@subsubsection Festplatten-Ein- und -Ausgaben

Bei Festplatten-Ein- und -Ausgaben benutzt InnoDB asynchrone Ein- und
Ausgaben. Unter Windows NT benutzt es die nativen Ein- und Ausgaben, die
vom Betriebssystem zur Verfügung gestellt werden. Unter Unix benutzt InnoDB
simulierte asynchrone Ein- und Ausgaben, die in InnoDB eingebaut sind:
InnoDB erzeugt eine Reihe von Ein-/Ausgabe-Threads, die sich um Ein- und
Ausgabeoperationen kümmern, zum Beispiel Vorwärts-Lesen (Read-Ahead).
Zukünftig werden wir auch für Windows NT simulierte Ein-/Ausgaben
unterstützen sowie für die Unix-Versionen, die so etwas besitzen, native
Ein-/Ausgaben.

Unter Windows NT benutzt InnoDB ungepufferte Ein- und Ausgaben. Das heißt,
dass die Festplatten-Seiten, die InnoDB liest oder schreibt, nicht im
Datei-Cache des Betriebssystems gepuffert werden. Das spart einiges an
Arbeitsspeicher-Bandbreite.

Ab Version 3.23.41 benutzt InnoDB eine neuartige Datei-Flush-Technik, die
Doublewrite heißt. Sie erhöht die Sicherheit bei Reparaturen nach Absturz,
wenn ein Betriebssystemabsturz oder ein Stromausfall aufgetreten sind, und
verbessert auf den meisten Unix-Versionen die Performance, indem die
Notwendigkeit von Fsync-Operationen verringert wird.

Doublewrite bedeutet, dass InnoDB zuerst in einen zusammenhängenden
Tabellenplatz (Tablespace) namens Doublewrite-Puffer schreibt, bevor Seiten
in eine Daten-Datei geschrieben werden. Erst nachdem das Schreiben und
Zurückschreiben (Flush) in den Doublewrite-Puffer fertig sind, schreibt
InnoDB die Seiten an ihre korrekten Positionen in der Daten-Datei. Wenn das
Betriebssystem mitten in einem Seiten-Schreiben abstürzt, findet InnoDB bei
der Wiederherstellung eine gute Kopie der Seite im Doublewrite-Puffer.

Ab Version 3.23.41 können Sie auch eine Raw-Disk-Partition als Daten-Datei
benutzen, obwohl das bisher noch nicht getestet wurde. Wenn Sie eine neue
Daten-Datei erzeugen, müssen Sie das Schlüsselwort @code{newraw}
unmittelbar nach der Daten-Datei-Größe in @code{innodb_data_file_path}
angeben. Die Partition muss größer oder gleich der Größe sein, die Sie
angeben. Beachten Sie, dass in InnoDB 1 MB 1024 x 1024 Bytes ist, während 1
MB in Festplatten-Spezifikationen üblicherweise 1.000.000 Bytes bedeutet.

@example
innodb_data_file_path=hdd1:5Gnewraw;hdd2:2Gnewraw
@end example

Wenn Sie die Datenbank wieder starten, @strong{müssen} -sue das
Schlüsselwort in @code{raw} ändern. Ansonsten schreibt InnoDB über Ihre
Partition!

@example
innodb_data_file_path=hdd1:5Graw;hdd2:2Graw
@end example

Wenn Sie Raw-Disk benutzen, können Sie unter einigen Unixen ungepufferte
Ein- und Ausgaben ausführen.

Es gibt zwei Vorwärts-Lesen-(Read-Ahead-)Heuristiken in InnoDB:
sequentielles Vorwärts-Lesen und wahlfreies (random) Vorwärts-Lesen. Beim
sequentiellen Vorwärts-Lesen bemerkt InnoDB, dass das Zugriffsschema auf
ein Segment im Tabellenplatz (Tablespace) sequentiell ist. InnoDB schickt
dann vorab einen Stapel von Lesevorgängen von Datenbankseiten an das
Ein-/Ausgabesystem. Beim wahlfreien Vorwärts-Lesen bemerkt InnoDB, dass ein
bestimmter Bereich im Tabellenplatz (Tablespace) im Zustand des vollständig
Eingelesenwerdens in den Puffer-Pool zu sein scheint. Dann schickt InnoDB
die verbleibenden Lesevorgänge an das Ein-/Ausgabesystem.


@node InnoDB File space, InnoDB File Defragmenting, InnoDB Disk I/O, File space management
@c German node Speicherplatz in InnoDB
@subsubsection Speicherplatzverwaltung

Die Daten-Dateien, die Sie in der Konfigurationsdatei definieren, formen
den Tabellenplatz (Tablespace) von InnoDB. Die Dateien werden einfach
verkettet, um den Tabellenplatz (Tablespace) zu formen, es wird kein
Striping benutzt. Momentan können Sie nicht direkt angeben, wo der Platz
für Ihre Tabellen zugewiesen werden soll, ausser wenn Sie folgende Tatsache
benutzen: InnoDB weist Speicherplatz von einem neu erzeugten Tabellenplatz
(Tablespace) vom niedrigen Ende ausgehend zu.

Der Tabellenplatz (Tablespace) besteht aus Datenbankseiten, deren
vorgabemäßige Größe 16 KB beträgt. Diese Seiten werden bis zu einer
Ausdehnung von 64 aufeinander folgenden Seiten gruppiert. Die 'Dateien'
innerhalb eines Tabellenplatzes (Tablespace) werden in InnoDB Segmente
genannt. Der Name des Rollback-Segments ist in gewisser Hinsicht
irreführend, weil dieses tatsächlich viele Segmente im Tabellenplatz
enthält.

Für jeden Index in InnoDB werden zwei Segmente zugewiesen: eins für die
Nicht-Blätter-Knoten (Non-Leaf-Nodes) des B-Baum, das andere für die
Blätter-Knoten. Die Idee dahinter ist, für die Blätter-Knoten, die die
Daten enthalten, bessere Sequentialität zu erzielen.

Wenn ein Segment innerhalb des Tabellenplatzes anwächst, weist ihm InnoDB
die ersten 32 Seiten individuell zu. Danach fängt InnoDB an, dem Segment
ganze Ausdehnungen zuzuweisen. InnoDB kann einem großen Segment bis zu
vier Ausdehnungen auf einmal hinzufügen, um gute Sequentialität für die
Daten sicherzustellen.

Einige Seiten im Tabellenplatz enthalten Bitmaps anderer Seiten. Daher
können einige Ausdehnungen in einem InnoDB-Tabellenplatz (Tablespace) nicht
Segmenten als Ganzes zugewiesen werden, sondern nur als individuelle
Seiten.

Wenn Sie eine Anfrage @code{SHOW TABLE STATUS FROM ... LIKE ...} ausführen,
um den verfügbaren freien Platz im Tabellenplatz festzustellen, berichtet
InnoDB den Platz, der in völlig freien Ausdehnungen im Tabellenplatz sicher
benutzt werden kann. InnoDB reserviert immer einige Ausdehnungen für
Säuberungs- und interne Zwecke. Diese Ausdehnungen werden nicht in den
freien Platz einbezogen.

Wenn Sie Daten aus einer Tabelle löschen, zieht InnoDB die entsprechenden
B-Baum-Indexe zusammen. Es hängt vom Schema der Löschvorgänge ab, ob das
individuelle Seiten oder Ausdehnungen im Tabellenplatz freigibt, so dass
der freigegebene Platz anderen Benutzern zur Verfügung steht. Wenn eine
Tabelle gelöscht wird oder alle Zeilen aus ihr gelöscht werden, gibt das
garantiert Platz frei für andere Benutzer, aber denken Sie daran, dass
gelöschte Zeile physikalisch nur durch eine Purge-Operation entfernt werden
können, nachdem Sie nicht mehr für ein Transaktions-Rollback oder für
Konsistentes Lesen benötigt werden.


@node InnoDB File Defragmenting,  , InnoDB File space, File space management
@c German node Datei-Defragmentierung in InnoDB
@subsubsection Eine Tabelle defragmentieren

Wenn es wahlfreie (random) Einfüge- oder Löschvorgänge in die Indexe einer
Tabelle gibt, können die Indexe fragmentiert werden. Unter Fragmentierung
verstehen wird, dass die physikalische Reihenfolge der Index-Seiten auf der
Platte der alphabetischen Reihenfolge der Datensätze auf den Seiten nicht
nahe kommt oder dass es viele unbenutzte Seiten in den 64-Seiten-Blöcken
gibt, die dem Index zugewiesen wurden.

Index-Scans können beschleunigt werden, wenn Sie von Zeit zu Zeit
@code{mysqldump} benutzen, um die Tabelle in eine Textdatei zu dumpen, dann
die Tabelle zu löschen und sie aus dem Dump neu aufzubauen. Eine weitere
Möglichkeit zur Defragmentierung besteht darin, den Tabellentyp in
@code{MyISAM} zu ändern (@code{ALTER}) und danach wieder in @code{InnoDB}
zurück. Beachten Sie, dass die @code{MyISAM}-Tabelle auf Ihrem
Betriebssystem in eine einzige Datei passen muss.

Wenn die Einfügungen in einen Index immer aufsteigend sind und Datensätze
nur vom Ende gelöscht werden, garantiert der
Speicherplatzverwaltungs-Algorithmus von InnoDB, dass keine Fragmentierung
im Index auftritt.


@node Error handling, InnoDB restrictions, File space management, InnoDB
@c German node Fehlerbehandlung
@subsection Fehlerbehandlung

Die Fehlerbehandlung in InnoDB ist nicht immer so, wie es die
ANSI-SQL-Standards festlegen. Nach ANSI-Standard sollte jeder Fehler
während eines SQL-Statements ein Rollback des Statements verursachen.
InnoDB rollt manchmal nur Teile des Statements oder auch die gesamte
Transaktion zurück. Folgende Liste gibt die Fehlerbehandlung von InnoDB an:

@itemize @bullet
@item
Wenn es keinen Speicherplatz mehr im Tabellenplatz (Tablespace) gibt,
bekommen Sie den MySQL-Fehler @code{'Table is full'} und InnoDB rollt das
SQL-Statement zurück.
@item
Eine Transaktions-Blockierung oder eine Zeitüberschreitung beim Warten auf
eine Sperre führen dazu, dass InnoDB die gesamte Transaktion zurückrollt.
@item
Ein Fehler wegen doppelter Schlüsseleinträge rollt das Einfügen dieser
Zeile zurück, selbst in einem Statement wie @code{INSERT INTO ... SELECT
...}. Das wird sich voraussichtlich ändern, so dass das SQL-Statement
zurückgerollt wird, wenn Sie die @code{IGNORE}-Option in Ihrem Statement
nicht angegeben haben.
@item
Ein Fehler 'row too long' rollt das SQL-Statement zurück.
@item
Andere Fehler werden zumeist durch die MySQL-Code-Ebene entdeckt und rollen
das entsprechende SQL-Statement zurück.
@end itemize


@node InnoDB restrictions, InnoDB contact information, Error handling, InnoDB
@c German node InnoDB-Einschränkungen
@subsection Beschränkungen von InnoDB-Tabellen

@itemize @bullet

@item
@strong{ACHTUNG:} Konvertieren Sie @strong{KEINE} MySQL-Systemtabellen von
MyISAM in InnoDB-Tabellen! Das wird nicht unterstützt. Wenn Sie es dennoch
tun, startet MySQL nicht mehr, bis Sie die alten Systemtabellen aus einer
Datensicherung wiederhergestellt haben oder sie mit dem
mysql_install_db-Skript neu erzeugen.

@item
@code{SHOW TABLE STATUS} gibt keine genauen Statistiken über
InnoDB-Tabellen, ausser über die physikalische Größe, die durch die
Tabelle reserviert wird. Der Zeilenzähler ist nur eine grobe Schätzung, die
bei der SQL-Optimierung benutzt wird.

@item
Wenn Sie versuchen, einen eindeutigen Index auf ein Präfix einer Spalte zu
erzeugen, erhalten Sie einen Fehler:

@example
CREATE TABLE T (A CHAR(20), B INT, UNIQUE (A(5))) TYPE = InnoDB;
@end example

Wenn Sie einen nicht eindeutigen Index auf ein Spaltenpräfix erzeugen,
erzeugt InnoDB einen Index über die gesamte Spalte.
@item
@code{INSERT DELAYED} wird für InnoDB-Tabellen nicht unterstützt.
@item
Die MySQL-@code{LOCK TABLES}-Operation weiß nichts von InnoDB-Sperren auf
Zeilenebene, die in bereits fertigen SQL-Statements gesetzt sind. Das
bedeutet, dass Sie eine Tabellensperre auf eine Tabelle selbst dann
erhalten können, wenn es noch Transaktionen anderer Benutzer gibt, die
Sperren auf Zeilenebene auf dieselbe Tabelle haben. Daher kann es sein,
dass Ihre Operationen auf die Tabelle warten müssen, wenn sie mit diesen
Sperren anderer Benutzer kollidieren. Auch eine Blockierung ist möglich.
Dennoch gefährdet das nicht die Transaktionsintegrität, weil sich die
Sperren auf Zeilenebene, die InnoDB setzt, um die Integrität kümmern.
Zusätzlich hindert eine Tabellensperren andere Transaktionen daran, weitere
Sperren auf Zeilenebene (in einem konfliktbehafteten Sperrmodus) auf die
Tabelle zu erlangen.
@item
Sie können keinen Schlüssel auf eine @code{BLOB}- oder @code{TEXT}-Spalte
setzen.
@item
Eine Tabelle kann nicht mehr als 1.000 Spalten enthalten.
@item
@code{DELETE FROM TABLE} erzeugt die Tabelle nicht neu, sondern löscht
statt dessen alle Zeilen, eine nach der anderen, was nicht sehr schnell
ist. In zukünftigen MySQL-Versionen können Sie @code{TRUNCATE} benutzen,
was schnell ist.
@item
Die vorgabemäßige Datenbank-Seitengröße in InnoDB beträgt 16 KB. Indem
Sie den Code neu kompilieren, können Sie sie auf Werte zwischen 8 KB und 64
KB setzen. Die maximale Zeilenlänge beträgt etwas weniger als die Hälfte
der Datenbank-Seite in den InnoDB-Versionen kleiner oder gleich 3.23.40. Ab
Quelldistribution 3.23.41 dürfen BLOB- und TEXT-Spalten bis zu 4 GB Groß
sein, die gesamte Zeilenlänge kann auch < 4 GB betragen. InnoDB speichert
Felder, deren Größe kleiner oder gleich 128 Bytes beträgt, nicht auf
separaten Seiten. Nachdem InnoDB die Zeile geändert hat, indem lange Felder
auf separaten Seiten gespeichert werden, muss die restliche Zeilenlänge
weniger als die Hälfte einer Datenbank-Seite betragen. Die maximale
Schlüssellänge beträgt 7.000 Bytes.
@item
Auf einigen Betriebssystemen müssen Daten-Dateien kleiner als 2 GB sein.
Die Gesamtgröße der Log-Dateien muss auf 32-Bit-Computern kleiner als 4 GB
sein.
@item
Die maximale Größe des Tabellenplatzes (Tablespace) beträgt 4 Milliarden
Datenbank-Seiten. Das ist auch die maximale Größe für eine Tabelle. Die
minimale Größe des Tabellenplatzes (Tablespace) beträgt 10 MB.
@end itemize


@node InnoDB contact information,  , InnoDB restrictions, InnoDB
@c German node InnoDB-Kontaktinformationen
@subsection InnoDB-Kontaktinformationen

Kontaktinformationen von Innobase Oy, Hersteller der InnoDB-Engine:
Website: @uref{http://www.innodb.com/}.
E-Mail: @email{Heikki.Tuuri@@innodb.com}

@example
Telefon: 358-9-6969 3250 (Büro) 358-40-5617367 (mobil)
Innobase Oy Inc.
World Trade Center Helsinki
Aleksanterinkatu 17
P.O.Box 800
00101 Helsinki
Finnland
@end example


@node BDB,  , InnoDB, Table types
@c German node BDB
@section BDB- oder Berkeley_db-Tabellen

@cindex Tabellen, @code{BDB}
@cindex Tabellen, @code{Berkeley DB}


@menu
* BDB overview::                
* BDB install::                 
* BDB start::                   
* BDB characteristics::         
* BDB TODO::                    
* BDB portability::             
* BDB errors::                  
@end menu

@node BDB overview, BDB install, BDB, BDB
@c German node BDB-Überblick
@subsection Überblick über BDB-Tabellen

Unterstützung für BDB-Tabellen ist in der MySQL-Quelldistribution seit
Version 3.23.34 enthalten und in der MySQL-Max-Binärdistribution aktiviert.

BerkeleyDB, erhältlich unter @uref{http://www.sleepycat.com/}, stattet
MySQL mit einem transaktionalen Tabellen-Handler aus. Wenn Sie
BerkeleyDB-Tabellen benutzen, haben Ihre Tabellen eine höhere Chance,
Abstürze zu überleben. Zusätzlich stehen @code{COMMIT} und @code{ROLLBACK}
für Transaktionen zur Verfügung. Die MySQL-Quelldistribution enthält eine
BDB-Distribution, die eine Reihe kleiner Patches hat, damit sie glatter mit
MySQL zusammen arbeitet. Sie können keine nicht gepatchte
@code{BDB}-Version für MySQL verwenden.

Wir bei MySQL AB arbeiten in enger Kooperation mit Sleepycat, um die hohe
Qualität der MySQL-/BDB-Schnittstelle zu halten.

Was den Support für BDB-Tabellen angeht, sehen wir uns in der Pflicht,
unseren Benutzern zu helfen, Probleme zu lokalisieren und Ihnen zu helfen,
einen reproduzierbaren Testfall für jegliche Probleme mit BDB-Tabellen zu
erstellen. Solche ein Fall wird an Sleepycat weiter geleitet, die sich dann
an uns wenden, um uns zu helfen, das Problem zu finden und zu beheben. Weil
das also in zwei Schritten abläuft, kann es bei jeglichen Problemen mit
BDB-Tabellen etwas länger dauern, diese zu lösen, als das bei anderen
Tabellen-Handlern der Fall ist. Weil jedoch der BerkeleyDB-Code selbst auch
von vielen sonstigen Applikationen benutzt wird, sind hierbei keine großen
Probleme zu erwarten. @xref{Support}.


@node BDB install, BDB start, BDB overview, BDB
@c German node BDB installieren
@subsection BDB installieren

Wenn Sie eine Binärdistribution von MySQL herunter geladen haben, die
Unterstützung für BerkeleyDB enthält, folgen Sie einfach den Anweisungen
zur Installation einer Binärversion von MySQL. @xref{MySQL binaries}.  @xref{mysqld-max, , @code{mysqld-max}}.

Um MySQL mit BerkeleyDB-Unterstützung zu kompilieren, laden Sie
MySQL-Version 3.23.34 oder neuer herunter und konfigurieren Sie
@code{MySQL} mit der @code{--with-berkeley-db}-Option.
@c German FIX unwrapped @xref
@xref{Installing source}.

@example
cd /pfad/zur/quelle/von/mysql-3.23.34
./configure --with-berkeley-db
@end example

Bitte sehen Sie wegen aktuellerer Informationen im Handbuch nach, das mit
der @code{BDB}-Distribution mitgeliefert wird.

Obwohl BerkeleyDB selbst sehr gut getestet und zuverlässig ist, wird die
MySQL-Schnittstelle noch als Beta-Qualität erachtet. Wir verbessern diese
aktiv und optimieren sie, um sie sehr bald stabil zu bekommen.


@node BDB start, BDB characteristics, BDB install, BDB
@c German node BDB starten
@subsection BDB-Startoptionen

Wenn Sie mit @code{AUTOCOMMIT=0} fahren, werden Ihre Änderungen in
@code{BDB}-Tabellen erst aktualisiert, wenn Sie @code{COMMIT} ausführen.
Statt dessen können Sie @code{ROLLBACK} ausführen, um Ihre Änderungen zu
verwerfen. @xref{COMMIT}.

Wenn Sie mit @code{AUTOCOMMIT=1} fahren (der Vorgabe), werden Ihre
Änderungen sofort abgeschickt. Sie können eine ausgedehnte Transaktion mit
dem SQL-Befehl @code{BEGIN WORK} starten. Danach werden Ihre Änderungen
solange nicht abgeschickt, bis Sie @code{COMMIT} ausführen (oder sich für
@code{ROLLBACK} entscheiden, um Ihre Änderungen zu verwerfen).

Folgende Optionen für @code{mysqld} können benutzt werden, um das Verhalten
von BDB-Tabellen zu ändern:

@multitable @columnfractions .30 .70
@item @strong{Option} @tab @strong{Beschreibung}
@item @code{--bdb-home=directory} 
 @tab Base Verzeichnis für BDB-Tabellen. Das sollte dasselbe Verzeichnis sein, das Sie für --datadir benutzen.
@item @code{--bdb-lock-detect=#} 
 @tab Berkeley-Sperr-Erkennung. # steht für DEFAULT, OLDEST, RANDOM oder YOUNGEST.
@item @code{--bdb-logdir=Verzeichnis}
 @tab BerkeleyDB-Log-Datei-Verzeichnis.
@item @code{--bdb-no-sync}
 @tab Flush-Logs nicht synchronisieren.
@item @code{--bdb-no-recover}
 @tab BerkeleyDB nicht im Wiederherstellungsmodus starten.
@item @code{--bdb-shared-data}
 @tab BerkeleyDB im Multi-Prozess-Modus starten (@code{DB_PRIVATE} bei der Initialisierung von BerkeleyDB nicht verwenden).
@item @code{--bdb-tmpdir=verzeichnis}
 @tab Name der temporären Datei von BerkeleyDB.
@item @code{--skip-bdb}
 @tab BerkeleyDB nicht benutzen.
@item @code{-O bdb_max_lock=1000}
 @tab Setzt die höchste Anzahl möglicher Sperren. @xref{SHOW VARIABLES}.
@end multitable

Wenn Sie @code{--skip-bdb} benutzen, initialisiert MySQL nicht die
BerkeleyDB-Bibliothek und spart deshalb viel Speicher. Natürlich können Sie
@code{BDB}-Tabellen nicht benutzen, wenn Sie diese Option verwenden.

Normalerweise sollten Sie @code{mysqld} ohne @code{--bdb-no-recover}
starten, wenn Sie vorhaben, BDB-Tabellen zu verwenden. Das kann allerdings
zu Problemen führen, wenn Sie @code{mysqld} starten und die BDB-Log-Dateien
beschädigt sind. @xref{Starting server}.

Mit @code{bdb_max_lock} können Sie die maximale Anzahl von Sperren
festlegen (vorgabemäßig 10.000), die auf einer BDB-Tabelle aktiv sein
können. Sie sollten diesen Wert herauf setzen, wenn Sie Fehler vom Typ
@code{bdb: Lock table is out of available locks} oder @code{Got error 12
from ...} erhalten, wenn Sie lange Transaktionen ausführen oder wenn
@code{mysqld} viele Zeilen untersuchen muss, um die Anfrage zu berechnen.

Sie könnten auch @code{binlog_cache_size} und @code{max_binlog_cache_size}
ändern, wenn Sie große, vielzeilige Transaktionen benutzen. @xref{COMMIT}.


@node BDB characteristics, BDB TODO, BDB start, BDB
@c German node BDB-Charakteristiken
@subsection Kennzeichen von @code{BDB}-Tabellen

@itemize @bullet
@item
Um Transaktionen zurückrollen zu können, unterhält BDB Log-Dateien. Um
maximale Performance zu erzielen, sollten Sie diese auf andere Festplatten
platzieren als Ihre Datenbanken, indem Sie die @code{--bdb_log_dir}-Option
benutzen.
@item
MySQL macht jedes Mal, wenn eine neue BDB-Log-Datei gestartet wird, einen
Checkpoint und entfernt alle Log-Dateien, die nicht für aktuelle
Transaktionen benötigt werden. Sie können auch jederzeit @code{FLUSH LOGS}
laufen lassen, um einen Checkpoint für die BerkeleyDB-Tabellen anzulegen.

Für die Wiederherstellung nach Abstürzen sollten Sie Datensicherungen der
Tabellen plus das Binär-Log von MySQL benutzen. @xref{Backup}.

@strong{Achtung}: Wenn Sie alte Log-Dateien löschen, die in Benutzung sind,
ist BDB nicht in der Lage, Wiederherstellungen durchzuführen, und Sie
könnten Daten verlieren, wenn etwas schief geht.
@item
MySQL erfordert einen @code{PRIMARY KEY} in jeder BDB-Tabelle, um auf
vorher gelesene Zeilen verweisen zu können. Wenn Sie keine Primärschlüssel
anlegen, erzeugt MySQL einen versteckten @code{PRIMARY KEY}. Der versteckte
Schlüssel hat eine Länge von 5 Bytes und wird bei jedem Einfügeversuch um 1
hochgezählt.
@item
Wenn alle Spalten, auf die Sie in einer @code{BDB}-Tabelle zugreifen, Teil
desselben Indexes oder Teil des Primärschlüssels sind, kann MySQL die
Anfrage ausführen, ohne auf die tatsächliche Zeile zugreifen zu müssen. Bei
einer @code{MyISAM}-Tabelle gilt das nur, wenn die Spalten Teil desselben
Indexes sind.
@item
Der @code{PRIMARY KEY} ist schneller als jeder andere Schlüssel, weil
@code{PRIMARY KEY} zusammen mit den Zeilendaten gespeichert wird. Weil die
anderen Schlüssel als Schlüsseldaten plus @code{PRIMARY KEY} gespeichert
werden, ist es wichtig, den @code{PRIMARY KEY} so kurz wie möglich zu
halten, um Plattenplatz zu sparen und bessere Geschwindigkeit zu erzielen.
@item
@code{LOCK TABLES} funktioniert bei @code{BDB}-Tabellen wie bei anderen
Tabellen. Wenn Sie @code{LOCK TABLE} nicht benutzen, führt MySQL einer
interne mehrfache Schreibsperre auf die Tabelle aus, um sicherzustellen,
dass die Tabelle korrekt gesperrt ist, wenn ein anderer Thread eine
Tabellensperre ausführt.
@item
Internes Sperren in @code{BDB}-Tabellen wird auf Seitenebene durchgeführt.
@item
@code{SELECT COUNT(*) FROM tabelle} ist langsam, weil @code{BDB}-Tabellen
keinen Zähler für die Anzahl der Zeilen in der Tabelle unterhalten.
@item
Scannen ist langsamer als bei @code{MyISAM}-Tabellen, weil Daten in
BDB-Tabellen in B-Bäumen und nicht in separaten Daten-Dateien gespeichert
werden.
@item
Die Applikation muss stets darauf vorbereitet sein, Fälle zu handhaben, bei
denen jegliche Änderung einer @code{BDB}-Tabelle zu einem automatischen
Rollback führen kann und jegliches Lesen fehlschlagen kann, weil ein
Blockierungsfehler auftritt.
@item
Schlüssel werden nicht auf vorherige Schlüssel komprimiert, wie das bei
ISAM- und MyISAM-Tabellen der Fall ist. Mit anderen Worten benötigt die
Schlüsselinformation etwas mehr Platz bei @code{BDB}-Tabellen im Vergleich
zu MyISAM-Tabellen, die nicht @code{PACK_KEYS=0} benutzen.
@item
Oft gibt es Löcher in der BDB-Tabelle, damit Sie neue Zeilen in der Mitte
des Schlüsselbaums einfügen können. Das macht BDB-Tabellen etwas größer
als MyISAM-Tabellen.
@item
Der Optimierer muss näherungsweise die Anzahl von Zeilen in der Tabelle
kennen. MySQL löst dieses Problem, indem Einfügeoperationen gezählt werden,
und unterhält diese in einem separaten Segment in jeder BDB-Tabelle. Wenn
Sie nicht viele @code{DELETE} oder @code{ROLLBACK} ausführen, sollte diese
Zahl ausreichend genau für den MySQL-Optimierer sein. Weil MySQL die Zahl
nur beim Schließen speichert, kann sie falsch sein, wenn MySQL unerwartet
stirbt. Das sollte kein schwerer Fehler sein, selbst wenn die Zahl nicht
100% korrekt ist. Man kann die Anzahl von Zeilen aktualisieren, indem man
@code{ANALYZE TABLE} oder @code{OPTIMIZE TABLE} ausführt.
@c German FIX Unsplit @xref
@xref{ANALYZE TABLE}. @xref{OPTIMIZE TABLE}.
@item
Wenn die Platte bei einer @code{BDB}-Tabelle voll wird, erhalten Sie einen
Fehler (wahrscheinlich Fehler 28) und die Transaktion sollte zurückgerollt
werden. Das steht im Gegensatz zu @code{MyISAM}- and @code{ISAM}-Tabellen,
bei denen @code{mysqld} wartet, bis genug Plattenplatz frei ist, bevor
weiter gemacht wird.
@end itemize


@node BDB TODO, BDB portability, BDB characteristics, BDB
@c German node BDB-TODO-Liste
@subsection Was in naher Zukunft bei BDB in Ordnung gebracht werden muss

@itemize @bullet
@item
Viele BDB-Tabellen zur gleichen Zeit öffnen ist sehr langsam. Wenn Sie
BDB-Tabellen benutzen wollen, sollten Sie einen sehr großen Tabellen-Cache
haben (evtl. größer als 256) und beim @code{mysql}-Client
@code{--no-auto-rehash} benutzen. Das soll partiell in Version 4.0 behoben
werden.
@item
@code{SHOW TABLE STATUS} gibt momentan noch nicht viele Informationen über
BDB-Tabellen aus.
@item
Performance optimieren.
@item
Es sollten überhaupt keine Seitensperren mehr benutzt werden, wenn Tabellen
gescannt werden.
@end itemize


@node BDB portability, BDB errors, BDB TODO, BDB
@c German node BDB-Portabilität
@subsection Betriebssysteme, die von @strong{BDB} unterstützt werden

Wenn Sie MySQL mit Unterstützung für BDB-Tabellen gebaut haben und
folgenden Fehler in der Log-Datei sehen, wenn Sie @code{mysqld} starten:

@example
bdb: architecture lacks fast mutexes: applications cannot be threaded
Can't init databases
@end example

Bedeutet das, dass @code{BDB}-Tabellen für Ihre Architektur nicht
unterstützt werden. In diesem Fall müssen Sie MySQL erneut bauen, ohne
Unterstützung für BDB-Tabellen.

HINWEIS: Folgende Liste ist nicht komplett. Sie wird aktualisiert, sobald
wir mehr Informationen darüber haben.

Momentan wissen wir, dass BDB-Tabellen auf folgenden Betriebssystemen
laufen:

@itemize @bullet
@item
Linux 2.x intel
@item
Solaris sparc
@item
Caldera (SCO) OpenServer
@item
Caldera (SCO) UnixWare 7.0.1
@end itemize

Auf folgenden Betriebssystemen läuft BDB nicht:

@itemize @bullet
@item
Linux 2.x Alpha
@item
Mac OS X
@end itemize


@node BDB errors,  , BDB portability, BDB
@c German node BDB-Fehler
@subsection Fehler, die bei der Benutzung von BDB-Tabellen auftreten können

@itemize @bullet
@item
Wenn Sie folgenden Fehler in der @code{hostname.err}-Log-Datei beim Start
von @code{mysqld} erhalten:

@example
bdb:  Ignoring log file: .../log.XXXXXXXXXX: unsupported log version #
@end example
Bedeutet das, dass die neue @code{BDB}-Version das alte Log-Dateiformat
nicht unterstützt. In diesem Fall müssen Sie alle @code{BDB}-Log-Dateien
aus Ihrem Datenbankverzeichnis löschen (die Dateien haben das Format
@code{log.XXXXXXXXXX}) und @code{mysqld} neu starten. Wir empfehlen
ausserdem, dass Sie @code{mysqldump --opt} auf Ihre alten
@code{BDB}-Tabellen ausführen, die alten Tabellen löschen und aus dem Dump
wiederherstellen.
@item
Wenn Sie im @code{auto_commit}-Modus fahren und eine Tabelle löschen, die
durch einen anderen Thread benutzt wird, erhalten Sie womöglich folgende
Fehlermeldungen in der MySQL-Fehlerdatei:

@example
001119 23:43:56  bdb:  Missing log fileid entry
001119 23:43:56  bdb:  txn_abort: Log undo failed for LSN: 1 3644744: Invalid
@end example

Das ist kein schwerer Fehler, aber wir empfehlen, alle Tabellen zu löschen,
wenn Sie nicht im @code{auto_commit}-Modus sind, bis dieses Problem behoben
ist (die Behebung ist nicht trivial).
@end itemize


@node Clients, Extending MySQL, Table types, Top
@c German node MySQL-APIs
@chapter MySQL-APIs

@cindex Client-Werkzeuge
@cindex APIs
@cindex @code{mysqlclient}-Bibliothek
@cindex Puffergrößen, Client
@cindex Bibliothek, @code{mysqlclient}


Dieses Kapitel beschreibt die APIs, die für MySQL bereitstehen, wo man sie 
bekommt und wie man sie benutzt. Die C-API ist am ausführlichsten beschrieben,
da sie vom MySQL-Team stammt und als Basis für die meisten anderen APIs 
dient.


@menu
* PHP::                         
* Perl::                        
* ODBC::                        
* C::                           
* Cplusplus::                   
* Java::                        
* Python::                      
* Tcl::                         
* Eiffel::                      
@end menu

@node PHP, Perl, Clients, Clients
@c German node PHP
@section MySQL-PHP-API

@cindex PHP-API

PHP ist eine serverseitige Skriptsprache, die in HTML eingebettet werden
kann und mit der man dynamische Webseiten erstellen kann. PHP unterstützt
eine Vielzahl von Datenbanken. Darunter befindet sich auch MySQL. PHP kann
als alleinstehendes Programm oder als Teil des Apache Webservers eingesetzt
werden.


Die Distribution und die Dokumentation gibt es unter 
@uref{http://www.php.net/, PHP-Website}.


@menu
* PHP problems::                
@end menu

@node PHP problems,  , PHP, PHP
@c German node PHP-Probleme
@subsection Allgemeine Probleme mit MySQL und PHP

@itemize @bullet
@item Error: "Maximum Execution Time Exceeded"
Dies ist eine PHP-Beschränkung. Ändern sie den Wert für die maximale
Ausführungszeit in der @file{php3.ini}-Datei. Es ist ausserdem keine
schlechte Idee, die Beschränkung für die maximale Benutzung von RAM von 8
MB auf 16 MB per Skript zu verdoppeln.


@item Error: "Fatal error: Call to unsupported oder undefined function mysql_connect() in .."
Das bedeutet, dass Ihre PHP-Version nicht mit MySQL-Unterstützung
ausgestattet ist. Sie können entweder ein dynamisches MySQL-Modul für PHP
kompilieren oder PHP mit seiner eingebautet MySQL-Unterstützung neu
kompilieren. Im PHP-Manual ist dies ausführlich beschrieben.

@item Error: "undefined reference to `uncompress'"
Die Client-Bibliothek wurde mit der Unterstützung für ein komprimiertes
Client-/Server-Protokoll kompiliert. Um den Fehler zu beheben, müssen Sie
@code{-lz} als letztes angeben, wenn Sie gegen @code{-lmysqlclient}
linken.
@end itemize


@node Perl, ODBC, PHP, Clients
@c German node Perl
@section MySQL-Perl-API

@cindex APIs, Perl
@cindex Perl-API

Dieser Abschnitt dokumentiert die Perl-@code{DBI}-Schnittstelle. Die
frühere Schnittstelle hieß @code{mysqlperl}.  @code{DBI}/@code{DBD} ist
jetzt die empfohlene Perl-Schnittstelle. @code{mysqlperl} ist überflüßig
und deshalb hier nicht näher beschrieben.



@menu
* DBI with DBD::                
* Perl DBI Class::              
* DBI-info::                    
@end menu

@node DBI with DBD, Perl DBI Class, Perl, Perl
@c German node DBI mit DBD
@subsection @code{DBI} mit @code{DBD::mysql}

@cindex @code{DBI}-Schnittstelle

@code{DBI} ist eine allgemeine Schnittstelle für viele Datenbanken. Das
bedeutet, Sie können ein Skript schreiben, dass viele verschiedene
Datenbanken unterstützt, ohne es zu ändern. Sie brauchen für jeden
Datenbanktyp einen Datenbank-Treiber (DBD). Für MySQL heißt dieser Treiber
@code{DBD::mysql}. Für weitere Informationen über Perl5 DBI besuchen Sie
bitte die @code{DBI}-Website und lesen Sie die Dokumentation:

@example
@uref{http://www.symbolstone.org/technology/perl/DBI/index.html}
@end example
Für weitere Informationen über objektorientierte Programmierung (OOP) in
Perl5 besuchen Sie die OOP-Seite:
@example
@uref{http://language.perl.com/info/documentation.html}
@end example

Beachten Sie, dass Sie, wenn Sie Transaktionen mit Perl einsetzen wollen,
@code{Msql-Mysql-modules} der Version 1.2216 oder neuer benötigen.

Installationsanweisungen für MySQL-Perl-Unterstützung finden Sie unter
@ref{Perl}.


@node Perl DBI Class, DBI-info, DBI with DBD, Perl
@c German node Perl-DBI-Klasse
@subsection Die @code{DBI}-Schnittstelle

@cindex @code{DBI}-Perl-Modul

@noindent
@strong{Portable DBI-Methoden}

@multitable @columnfractions .3 .7
@item @code{connect} @tab Errichtet eine Verbindung zum Datenbankserver.
@item @code{disconnect} @tab Trennt eine Verbindung zum Datenbankserver.
@item @code{prepare} @tab Bereitet ein SQL-Statement zur Abfrage vor.
@item @code{execute} @tab Führt eine vorbereitetes Statement aus.
@item @code{do}      @tab Bereitet ein SQL-Statement vor und führt es aus.
@item @code{quote}   @tab Quotet eine Zeichenkette oder einen @code{BLOB}-Wert zum Einfügen.
@item @code{fetchrow_array} @tab Holt die nächste Zeile als einen Array aus Feldern.
@item @code{fetchrow_arrayref} @tab Holt die nächste Zeile als eine Referenz eines Arrays aus Feldern.
@item @code{fetchrow_hashref} @tab Holt die nächste Zeile als eine Referenz einer Hash-Tabelle.
@item @code{fetchall_arrayref} @tab Holt alle Zeilen als einen Array von Arrays.
@item @code{finish}  @tab Beendet ein Statement und läßt das System Resourcen freigeben.
@item @code{rows}    @tab Gibt die Anzahl der betroffenen Zeilen zurück.
@item @code{data_sources} @tab Gibt einen Array mit den verfügbaren Daten auf localhost zurück.
@item @code{ChopBlanks} @tab Kontroliert, ob die @code{fetchrow_*}-Methoden Leerzeichen entfernen.
@item @code{NUM_OF_PARAMS} @tab Die Anzahl der Platzhalter in einem vorbereiteten Statement.
@item @code{NULLABLE} @tab Welche Spalten @code{NULL} sein können.
@item @code{trace}    @tab Tracen zum Debuggen ausführen.
@end multitable

@noindent
@strong{MySQL-spezifische Methoden}

@multitable @columnfractions .3 .7
@item @code{insertid} @tab Der letzte @code{AUTO_INCREMENT}-Wert.
@item @code{is_blob} @tab Welche Spalten @code{BLOB}-Werte sind.
@item @code{is_key} @tab Welche Spalten Schlüssel sind.
@item @code{is_num} @tab Welche Spalten numerisch sind.
@item @code{is_pri_key} @tab Welche Spalten Primärschlüssel sind.
@item @code{is_not_null} @tab Welche Spalten NICHT @code{NULL} sein können. Siehe auch @code{NULLABLE}.
@item @code{length} @tab Maximal mögliche Spaltengröße.
@item @code{max_length} @tab Maximale Spaltengröße, die im aktuellen Ergebnis enthalten ist.
@item @code{NAME} @tab Spaltennamen.
@item @code{NUM_OF_FIELDS} @tab Anzahl der zurückgegebenen Felder.
@item @code{table} @tab Tabellennamen im zurückgegebenen Ergebnis.
@item @code{type} @tab Alle Spaltentypen.
@end multitable

Die Perl-Methoden werden im Folgenden detaillierter erläutert. Die
Variablen für die zurückgegebenen Werte haben folgende Bedeutung:

@table @code
@item $dbh
Datenbank-Handle

@item $sth
Statement-Handle

@item $rc
Rückgabe-Code (oft ein Status)

@item $rv
Rückgabewert (oft ein Status)
@end table

@noindent
@strong{Portable DBI-Methoden}

@table @code

@findex DBI->connect()
@findex connect()-DBI-Methode
@item connect($datenquelle, $benutzername, $passwort)
Benutzen Sie die @code{connect}-Methode, um eine Verbindung zur Datenbank
der Datenquelle herzustellen. Der @code{$datenquelle}-Wert sollte mit
@code{DBI:Treiber_name:} beginnen. Beispielanwendungen von @code{connect}
mit dem @code{DBD::mysql} Treiber:
@example
$dbh = DBI->connect("DBI:mysql:$datenbank", $benutzer, $passwort);
$dbh = DBI->connect("DBI:mysql:$datenbank:$hostname",
                    $benutzer, $passwort);
$dbh = DBI->connect("DBI:mysql:$datenbank:$hostname:$port",
                    $benutzer, $passwort);
@end example
Wenn der Benutzername und / oder das Passwort nicht angegeben werden,
verwendet @code{DBI} die Werte der @code{DBI_USER}- und @code{DBI_PASS}-
Umgebungsvariablen. Wen Sie keinen Hostnamen angeben, wird @code{'localhost'}
verwendet. Wenn Sie keine Portnummer angeben, wird der MySQL-Port 
(@value{default_port}) verwendet.

Seit @code{Msql-Mysql-modules}-Version 1.2009 erlaubt der 
@code{$datenquelle}-Wert bestimmte Modifikatoren:

@table @code
@item mysql_read_default_file=datei
Liest @file{datei} als eine Optionsdatei. Für weitere Informationen zu 
Optionsdateien beachten Sie bitte @ref{Option files}.

@item mysql_read_default_group=group_name
Beim Lesen einer Optionsdatei ist die Standardgruppe normalerweise die
@code{[client]}-Gruppe. Wenn Sie die @code{mysql_read_default_group}-
Option angeben, wird die Standardgruppe @code{[gruppenname]}.

@item mysql_compression=1
Aktiviert die Kompression während der Kommunikation zwischen Client und
Server (ab Version 3.22.3).

@item mysql_socket=/pfad/zur/socket
Gibt den Pfad des Unix-Sockets an, der zum Verbinden mit dem
Server verwendet wird (MySQL-Version 3.21.15 oder neuer).
@end table

Sie können mehrere Modifikatoren angeben, dabei muss jedem ein Semikolon 
vorangestellt sein.

Wenn Sie zum Beispiel vermeiden wollen, dass sie Benutzername und Passwort
im @code{DBI}-Skript angeben müssen, können Sie sie aus der
@file{~/.my.cnf}-Optionsdatei nehmen. Ihr @code{connect}-Aufruf sieht
folgendermaßen aus:

@example
$dbh = DBI->connect("DBI:mysql:$datenbank"
                . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf",
                $benutzer, $passwort);
@end example

Dieser Aufruf liest die Optionen für die @code{[client]}-Gruppe aus der
Optionsdatei. Wenn Sie dasselbe für die @code{[perl]}-Gruppe tun wollen, 
könnte Ihr Code so aussehen:

@example
$dbh = DBI->connect("DBI:mysql:$Datenbank"
                . ";mysql_read_default_file=$ENV@{HOME@}/.my.cnf"
                . ";mysql_read_default_group=perl",
                $benutzer, $passwort);
@end example

@findex DBI->disconnect
@findex disconnect-DBI-Methode
@item disconnect
Die @code{disconnect}-Methode beendet die Verbindung mit der Datenbank.
Dies wird typischerweise kurz vor dem Ende eines Scripts ausgeführt.
Beispiel:
@example
$rc = $dbh->disconnect;
@end example

@findex DBI->prepare()
@findex prepare()-DBI-Methode
@item prepare($statement)
Bereitet ein SQL-Statement zum Ausführen durch den Datenbankserver vor und
gibt ein "Statement-Handle" @code{($sth)} zurück, mit der Sie die
@code{execute}-Methode aufrufen.
Normalerweise werden Sie @code{SELECT}-Statements (und
@code{SELECT}-ähnliche Statements so wie @code{SHOW}, @code{DESCRIBE} und
@code{EXPLAIN}) mit der Bedeutung von @code{prepare} und @code{execute}
verwenden.
Beispiel:
@example
$sth = $dbh->prepare($statement)
    or die "$statement: $dbh->errstr kann nicht vorbereitet werden\n";
@end example

@findex DBI->execute
@findex execute-DBI-Methode
@item execute
Die @code{execute}-Methode führt ein vorbereitetes Statement aus. Bei
Nicht-@code{SELECT}-Statements gibt @code{execute} die Anzahl der
betroffenen Zeilen zurück. Wenn Zeilen betroffen sind, gibt @code{execute}
@code{"0E0"} zurück, was in Perl als 0 und true erkannt wird. Wenn ein
Fehler auftritt, gibt @code{execute} @code{undef} zurück. Bei
@code{SELECT}-Statements beginnt @code{execute} die SQL-Anfrage in der
Datenbank; Sie müssen eine der @code{fetch_*}-Methoden nutzen, die weiter
unten beschrieben sind, um Daten erhalten. Beispiel:
@example
$rv = $sth->execute
          or die "Die Query: $sth->errstr kann nicht ausgeführt werden.";
@end example

@findex DBI->do()
@findex do()-DBI-Methode
@item do($statement)
Die @code{do}-Methode bereitet ein Statement vor, führt es aus und gibt die
Anzahl der betroffenen Zeilen zurück. Wenn Zeilen betroffen sind, gibt
@code{execute} @code{"0E0"} zurück, was in Perl als 0 und true erkannt
wird. Diese Methode wird normalerweise verwendet, um
Nicht-@code{SELECT}-Statements zu bearbeiten, die (z. B. wegen
Treiber-Beschränkungen) nicht vorbereitet werden können, oder die nicht
mehr als einmal vorbereitet werden müssen (INSERTS, DELETE usw.). Beispiel:
@example
$rv = $dbh->do($statement)
        or die "$statement: $dbh- >errstr kann nicht vorbereitet werden\n";
@end example

Im Allgemeinen ist die @code{do}-Methode VIEL schneller (und vorzuziehen)
als die @code{prepare}/@code{execute}-Methoden, die ohne Parameter
aufgerufen werden.

@findex DBI->quote()
@findex quote()-DBI-Methode
@cindex Zeichenketten quoten
@cindex Zeichenketten, quoten
@item quote($string)
Die @code{quote}-Methode wird verwendet, um Sonderzeichen zu "escapen", die
in Zeichenketten enthalten sein können, und um notwendige äußere
Anführungszeichen hinzuzufügen. Beispiel:
@example
$sql = $dbh->quote($string)
@end example

@findex DBI->fetchrow_array
@findex fetchrow_array-DBI-Methode
@item fetchrow_array
Die Methode holt die nächste Datenzeile und gibt sie als ein Array mit den
Feldwerten zurück. Beispiel:
@example
while(@@row = $sth->fetchrow_array) @{
        print qw($row[0]\t$row[1]\t$row[2]\n);
@}
@end example

@findex DBI->fetchrow_arrayref
@findex fetchrow_arrayref-DBI-Methode
@item fetchrow_arrayref
Die Methode holt die nächste Datenzeile und gibt sie als eine Referenz auf
ein Array mit den Feldwerten zurück. Beispiel:
@example
while($row_ref = $sth->fetchrow_arrayref) @{
        print qw($row_ref->[0]\t$row_ref->[1]\t$row_ref->[2]\n);
@}
@end example

@findex DBI->fetchrow_hashref
@findex fetchrow_hashref-DBI-Methode
@item fetchrow_hashref
Diese Methode holt eine Datenzeile und gibt eine Referenz auf einen Hash
zurück, der Name-/Wert-Paare enthält. Die Methode ist lange nicht so
performant wie das Verwenden von Referenzen auf ein Array, wie weiter oben
beschrieben ist. Beispiel:
@example
while($hash_ref = $sth->fetchrow_hashref) @{
        print qw($hash_ref->@{vorname@}\t$hash_ref->@{nachname@}\t\
                $hash_ref- > title@}\n);
@}
@end example

@findex DBI->fetchall_arrayref
@findex fetchall_arrayref-DBI-Methode
@item fetchall_arrayref
Diese Methode gibt alle Zeilen eines Ergebnisses einer SQL-Anfrage zurück.
Sie gibt eine Referenz auf ein Array mit Referenzen auf Arrays mit den
Werten der einzelnen Zeilen zurück. Sie können mit zwei verschachtelten
Schleifen auf die Werte zugreifen. Beispiel:
@example
my $table = $sth->fetchall_arrayref
                or die "$sth->errstr\n";
my($i, $j);
for $i ( 0 .. $#@{$table@} ) @{
        für $j ( 0 .. $#@{$table->[$i]@} ) @{
                print "$table->[$i][$j]\t";
        @}
        print "\n";
@}
@end example

@findex DBI->finish
@findex finish-DBI-Methode
@item finish
Bewirkt, dass keine weiteren Daten von dem SQL-Anfrageergebnis geholt
werden. Sie können diese Methode aufrufen, um Systemressourcen freizugeben.
Beispiel:
@example
s$rc = $sth->finish;
@end example

@findex DBI->rows
@findex rows-DBI-Methode
@item rows
Gibt die Anzahl der veränderten Zeilen (die aktualisiert oder gelöscht
wurden) des letzten Befehls zurück. Dies wird normalerweise nach
Nicht-@code{SELECT}-@code{execute}-Statements verwendet. Beispiel:
@example
$rv = $sth->rows;
@end example

@findex DBI->@{NULLABLE@}
@findex NULLABLE-DBI-Methode
@item NULLABLE
Gibt eine Referenz auf ein Array mit Boole'schen Werten zurück; für jedes
Element TRUE kann die Spalte @code{NULL}-Werte enthalten. Beispiel:
@example
$null_possible = $sth->@{NULLABLE@};
@end example

@findex DBI->@{NUM_OF_FIELDS@}
@findex NUM_OF_FIELDS-DBI-Methode
@item NUM_OF_FIELDS
Dieses Attribut enthält die Anzahl der Zeilen, die eine @code{SELECT}- oder
@code{SHOW FIELDS}-SQL-Anfrage zurückgibt. Sie können es verwenden, um zu
prüfen, ob eine Anfrage ein Ergebnis zurückgegeben hat: 0 weist auf eine
Nicht-@code{SELECT}-Anfrage hin, wie @code{INSERT}, @code{DELETE} oder
@code{UPDATE}. Beispiel:
@example
$nr_of_fields = $sth->@{NUM_OF_FIELDS@};
@end example

@findex DBI->datasource()
@findex datasource()-DBI-Methode
@item datasource($Treiber_name)
Diese Methode gibt einen Array zurück, der die Namen der verfügbaren
Datenbanken auf @code{'localhost'} enthält. Beispiel:
@example
@@dbs = DBI->datasource("mysql");
@end example

@findex DBI->@{ChopBlanks@}
@findex ChopBlanks-DBI-Methode
@item ChopBlanks
Dieses Attribut gibt an, ob die @code{fetchrow_*}-Methoden vor- und
nachstehende Leerzeichen entfernen. Beispiel:
@example
$sth->@{'ChopBlanks'@} =1;
@end example

@findex DBI->trace
@findex trace-DBI-Methode
@item trace($trace_ebene)
@itemx trace($trace_ebene, $trace_dateiname)
@code{trace} aktiviert oder deaktiviert "Tracing".
Wenn @code{DBI} als eine Klassenmethode aufgerufen wird, steuert es das
"Tracing" mit allen Datenbankverbindungen. Wenn es als Datenbank- oder
Statement-Handle-Methode aufgerufen wird, steuert es nur die verwendete
Verbindung (und deren spätere Ableitungen). Wenn Sie @code{$trace_ebene}
auf 2 setzen, bewirkt es detaillierte Informationen. Der Wert 0 stellt
"Tracing" ab. Die Ausgabe des "Tracing" wird vorgabemäßig nach "standard
error" geleitet. Wenn @code{$trace_dateiname} angegeben ist, wird die
Ausgabe für @emph{alle} "getraceten" Verbindungen an das Ende dieser Datei
geschrieben. Beispiel:
@example
DBI->trace(2);                # alles tracen
DBI->trace(2,"/tmp/dbi.out"); # alles nach /tmp/dbi.out tracen
$dth->trace(2);               # diese Datenbankverbindung tracen
$sth->trace(2);               # dieses Statement-Handle tracen.
@end example

@tindex @code{DBI_TRACE}-Umgebungsvariable
@tindex Umgebungsvariable, @code{DBI_TRACE}
Sie können @code{DBI}-Tracing auch anschalten, indem Sie die
@code{DBI_TRACE}-Umgebungsvariable setzen. Wenn Sie sie auf einen
numerischen Wert setzen, ist das dasselbe, wie @code{DBI->(wert)}
aufzurufen. Wenn Sie sie auf einen Pfadnamen setzen, ist das dasselbe, wie
@code{DBI->(2,wert)} aufzurufen.

@end table

@noindent
@strong{MySQL-spezifische Methoden}

Die unten stehenden Methoden sind MySQL-spezifisch und nicht Teil des
@code{DBI}-Standards. Mehrere von ihnen sind veraltet:
@code{is_blob}, @code{is_key}, @code{is_num}, @code{is_pri_key},
@code{is_not_null}, @code{length}, @code{max_length} und @code{table}.
Wo immer es @code{DBI}-Standard-Alternativen gibt, ist das unten angemerkt:

@table @code
@findex DBI->@{insertid@}
@findex insertid-DBI-Methode
@tindex AUTO_INCREMENT, Benutzung bei DBI
@item insertid
Wenn Sie das @code{AUTO_INCREMENT}-Feature von MySQL benutzen, werden neue,
automatisch heraufgezählte Werte hier gespeichert. Beispiel:
@example
$new_id = $sth->@{insertid@};
@end example

Alternativ können Sie @code{$dbh->@{'mysql_insertid'@}} verwenden.

@findex DBI->@{is_blob@}
@findex is_blob-DBI-Methode
@item is_blob
Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
ein @code{BLOB} ist. Beispiel:
@example
$keys = $sth->@{is_blob@};
@end example

@findex DBI->@{is_key@}
@findex is_key-DBI-Methode
@item is_key
Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
ein Schlüssel ist. Beispiel:
@example
$keys = $sth->@{is_key@};
@end example

@findex DBI->@{is_num@}
@findex is_num DBI-Methode
@item is_num
Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
numerische Werte enthält. Beispiel:
@example
$nums = $sth->@{is_num@};
@end example

@findex DBI->@{is_pri_key@}
@findex is_pri_key DBI-Methode
@item is_pri_key
Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
Element des Arrays bedeutet der Wert TRUE, dass die entsprechende Spalte
ein Primärschlüssel ist. Beispiel:
@example
$pri_keys = $sth->@{is_pri_key@};
@end example

@findex DBI->@{is_not_null@}
@findex is_not_null DBI-Methode
@item is_not_null
Gibt eine Referenz auf einen Array mit Boole'schen Werten zurück; für jedes
Element des Arrays bedeutet der Wert FALSE, dass die entsprechende Spalte
NULL enthalten kann. Beispiel:
@example
$not_nulls = $sth->@{is_not_null@};
@end example

Das oben beschriebene @code{NULLABLE}-Attribut ist @code{is_not_null} in
jedem Fall vorzuziehen, da es zum DBI-Standard gehört.

@findex DBI->@{length@}
@findex length-DBI-Methode
@findex DBI->@{max_length@}
@findex max_length-DBI-Methode
@item length
@itemx max_length
Beide Methoden geben je einen Array mit Spaltenlängen zurück. Der
@code{length}-Array gibt die maximal mögliche Länge jeder Spalte an (wie es
in der Tabellendefinition festgelegt wurde). Der @code{max_length}-Array
gibt die Länge des aktuell längsten Wertes in den Spalten an. Beispiel:
@example
$lengths = $sth->@{length@};
$max_lengths = $sth->@{max_length@};
@end example

@findex DBI->@{NAME@}
@findex NAME-DBI-Methode
@item NAME
Gibt eine Referenz auf ein Array mit den Spaltennamen zurück. Beispiel:
@example
$names = $sth->@{NAME@};
@end example

@findex DBI->@{table@}
@findex table-DBI-Methode
@item table
Gibt eine Referenz auf ein Array mit den Tabellennamen zurück. Beispiel:
@example
$tables = $sth->@{table@};
@end example

@findex DBI->@{type@}
@findex type-DBI-Methode
@item type
Gibt eine Referenz auf ein Array mit den Spaltentypen zurück. Beispiel:
@example
$types = $sth->@{type@};
@end example

@end table


@node DBI-info,  , Perl DBI Class, Perl
@c German node DBI-Informationen
@subsection Weitere @code{DBI}/@code{DBD}-Informationen

@cindex @code{DBI/DBD}

Bitte verwenden Sie den @code{perldoc}-Befehl, um weitere Informationen
über @code{DBI} zu erhalten.

@example
perldoc DBI
perldoc DBI::FAQ
perldoc DBD::mysql
@end example

Sie können ausserdem @code{pod2man}, @code{pod2html} usw. verwenden, um in
andere Formate zu wandeln.

Die neuesten @code{DBI}-Informationen finden Sie auf der @code{DBI} Website:
@example
@uref{http://www.symbolstone.org/technology/perl/DBI/index.html}
@end example


@node ODBC, C, Perl, Clients
@c German node ODBC
@section MySQL-ODBC-Unterstützung

@cindex ODBC
@cindex Windows
@cindex MyODBC



MySQL unterstützt ODBC mit Hilfe des @strong{MyODBC}-Programms. Dieses
Kapitel erläutert, wie Sie @strong{MyODBC} installieren und benutzen. Hier
werden Sie außerdem eine Liste von Programmen finden, die mit
@strong{MyODBC} zusammenarbeiten.

@menu
* Installing MyODBC::           
* ODBC administrator::          
* MyODBC connect parameters::   
* ODBC Problems::               
* MyODBC clients::              
* ODBC and last_insert_id::     
* MyODBC bug report::           
@end menu

@node Installing MyODBC, ODBC administrator, ODBC, ODBC
@c German node MyODBC-Installation
@subsection Wie Sie MyODBC installieren

@strong{MyODBC} ist ein 32-Bit-ODBC- (2.50) -Level-0- (mit Level-1- und
Level-2-Features) Treiber für die Anbindung an ODBC-fähige Applikationen an
MySQL. @strong{MyODBC} funktioniert unter Windows95, Windows98, NT, und
auf den meisten Unix-Plattformen.

@strong{MyODBC} ist "public domain". Sie finden die neueste Version bei
@uref{http://www.mysql.com/downloads/api-myodbc.html}.

Wenn Sie ein Problem mit @strong{MyODBC} haben und Ihr Programm auch
mit OLEDB arbeitet, sollten sie den OLEDB Treiber probieren, den sie im
"Contrib"-Abschnitt finden.  @xref{Contrib}.

Normalerweise müssen Sie @strong{MyODBC} nur auf Windows-Maschinen
installieren. Sie brauchen @strong{MyODBC} für Unix nur, wenn sie ein
Programm wie ColdFusion haben, das auf einer Unix-Maschine läuft und ODBC
für die Datenbankverbindung nutzt.

Wenn Sie @strong{MyODBC} unter Unix installieren wollen, brauchen Sie noch
einen @strong{ODBC}-Manager. @strong{MyODBC} arbeitet mit den meisten
Unix-ODBC-Managern zusammen.
@c German FIX node doesn't exist, should probably be to Portals?
@c Eine Liste finden Sie in dem @strong{ODBC}-verwandten Linkabschnitt
@c auf der MySQL-Seite @xref{Nützliche Links}.

Um @strong{MyODBC} unter Windows zu installieren, sollten sie die passende
@strong{MyODBC} Zip-Datei (für Windows 95/98 oder NT / Windows 2000)
herunterladen, es mit @code{WINZIP} oder einem ähnlichen Programm
entpacken, und die @code{SETUP.EXE}-Datei ausführen.

Unter Windows NT kann folgender Fehler während der Installation auftreten
(@strong{MyODBC}):

@example
Während des Kopiervorgangs ist ein Fehler aufgetreten:
C:\WINDOWS\SYSTEM\MFC30.DLL. Starten Sie Windows neu und beginnen die
Installation erneut, noch bevor sie ein anderes Programm starten, das ODBC
verwendet.
@end example

Das Problem in diesem Fall ist, dass ein anderes Programm ODBC verwendet
und dass unter Windows zwei Programme nicht gleichzeitig auf eine Datei
zugreifen können. Deshalb kann es sein, dass Sie nicht in der Lage sind,
die ODBC-Treiber mit Microsofts ODBC Setup Programm zu installieren. In den
meisten Fällen genügt es, den @code{Ignorieren}-Knopf zu drücken, um die
restlichen Dateien zu installieren und die Installation abzuschließen. Wenn
das nicht funktioniert, booten Sie Ihren Rechner im Abgesicherten Modus,
indem sie F8 vor dem Starten von Windows drücken und den Abgesicherten
Modus auswählen. Installieren sie @strong{MyODBC}, und starten Sie wieder
im normalen Modus.

@itemize @bullet
@item
Um eine Verbindung mit einer ODBC-Applikation, die MySQL nicht nativ
unterstützt, von Windows zu Unix herzustellen, müssen Sie zunächst
@strong{MyODBC} unter Windows installieren.
@item
Der Windows-Benutzer muss Zugriffsrechte auf den MySQL-Server der
Unix-Maschine besitzen. Diese richten Sie mit dem @code{GRANT}-Befehl ein.
@xref{GRANT,,@code{GRANT}}.
@item
Sie müssen wie folgt einen ODBC-DSN-Eintrag erstellen:

@itemize @minus
@item
Öffnen Sie die Systemsteuerung der Windows-Maschine.
@item
Doppelklicken Sie das ODBC-Datenquellen-Symbol.
@item
Klicken Sie auf die Registerkarte Benutzer-DSN.
@item
Klicken Sie auf Hinzufügen.
@item
Wählen Sie MySQL im Fenster "Neue Datenquelle hinzufügen" und klicken Sie
auf den Fertig-Knopf.
@item
Das MySQL-Treiber-Standard-Konfigurationsfenster wird nun angezeigt.
@xref{ODBC administrator}.
@end itemize

@item
Starten Sie nun ihre Applikation und wählen Sie den ODBC-Treiber mit der
von ihnen im ODBC angegebenen DSN.
@end itemize

Bitte beachten Sie, dass weitere Konfigurationsoptionen im MySQL-Fenster
vorhanden sind (trace, don't prompt on connect usw.). Probieren Sie diese
aus, wenn Sie Probleme haben.

@node ODBC administrator, MyODBC connect parameters, Installing MyODBC, ODBC
@c German node ODBC-Administrator
@subsection Wie Sie die verschiedenen Felder im ODBC-Administrator Programm ausfüllen

@cindex ODBC, Administrator

Es gibt drei Möglichkeiten, den Server unter Windows 95 anzugeben:

@itemize @bullet
@item
Verwenden Sie die IP-Adresse des Servers.
@item
Fügen Sie der Datei @file{\windows\lmhosts} folgende Informationen an:

@example
ip hostname
@end example

Beispiel:

@example
194.216.84.21 mein_hostname
@end example

@item
Konfigurieren Sie DNS:
@end itemize

Beispiel: Wie Sie das @code{ODBC setup} ausfüllen:
@example
Windows DSN Name:   test
Beschreibung:       Das ist meine Datenbank
MySql Datenbank:    test
Server:             194.216.84.21
User:               monty
Password:           mein_passwort
Port:
@end example

Der Wert für @code{Windows DSN Namen} muss in ihrem Windows-ODBC-Setup
eindeutig sein.

Sie müssen die Werte für @code{Server}, @code{User}, @code{Password} oder
@code{Port} im ODBC-Setup-Fenster nicht angeben. Wenn Sie es jedoch tun,
werden diese Werte als Standardwerte verwendet, wenn Sie versuchen, eine
Verbindung aufzubauen. Sie können die Werte auch zur Laufzeit ihres
Programms angeben.

Wenn Sie die Portnummer nicht angeben, wird der Standard-Port
(@value{default_port}) verwendet.

Wenn Sie die Option @code{Optionen aus C:\my.cnf lesen} angeben, werden die
Gruppen @code{client} und @code{odbc} aus der @file{C:\my.cnf}-Datei
gelesen. Sie können alle Optionen verwenden, die für @code{mysql_options()}
gültig sind. @xref{mysql_options, , @code{mysql_options}}.


@node MyODBC connect parameters, ODBC Problems, ODBC administrator, ODBC
@c German node MyODBC-Verbindungsparameter
@subsection Verbindungsparameter für MyODBC

Man kann die folgenden Parameter für @strong{MyODBC} im
@code{[Servername]}-Abschnitt in der @code{ODBC.INI}-Datei oder über das
@code{InConnectionString}-Argument im @code{SQLDriverConnect()}-Aufruf
angeben:

@multitable @columnfractions .2 .2 .6
@item @strong{Parameter} @tab @strong{Standardwert} @tab @strong{Bedeutung}
@item user @tab ODBC (unter Windows) @tab Der Benutzername, der verwendet wird, um zu MySQL zu verbinden.
@item server @tab localhost @tab Der Hostname des MySQL-Servers.
@item database @tab @tab Die Standarddatenbank
@item option @tab 0 @tab Eine Ganzzahl, die angibt, wie @strong{MyODBC} arbeiten soll. Siehe unten.
@item port @tab 3306 @tab Der TCP/IP-Port, der verwendet werden soll, wenn der @code{server} nicht @code{localhost} ist.
@item stmt @tab @tab Ein Statement, das bei der Verbindung zu @code{MySQL} ausgeführt wird.
@item password @tab @tab Das Passwort für die @code{server}-@code{user}-Kombination.
@item socket @tab @tab Der Socket oder die Windows-Pipe, über die verbunden werden soll.
@end multitable

Die Option "argument" wird verwendet, um @strong{MyODBC} zu sagen, dass der
Client nicht 100% ODBC-kompatibel ist. Unter Windows setzt man diese Option
normalerweise im Verbindungsdialog, Sie können aber auch das
"option"-Argument verwenden. Die folgenden Optionen sind in derselben
Reihenfolge wie im @strong{MyODBC}-Verbindungsdialog:

@multitable @columnfractions .1 .9
@item @strong{Bit} @tab @strong{Bedeutung}
@item 1 @tab Der Client kann nicht damit umgehen, dass @strong{MyODBC} die wirkliche Breite einer Spalte zurückgibt.
@item 2 @tab  Der Client kann nicht damit umgehen, dass MySQL die wirkliche Anzahl an "affected rows" zurückgibt. Wenn dieses Bit gesetzt ist, wird MySQL statt dessen 'found rows' zurückgeben. Dies wird erst ab MySQL 3.21.14 unterstützt.
@item 4 @tab Erstellt ein Debug-Log in c:\myodbc.log. Das ist dasselbe, als wenn Sie @code{MYSQL_DEBUG=d:t:O,c::\myodbc.log} in Ihre @file{AUTOEXEC.BAT} schreiben.
@item 8  @tab Entfernt jede Paket-Beschränkung für Ergebnisse und Parameter.
@item 16 @tab Nicht auf Eingaben warten, sogar wenn der Treiber dies verlangt.
@item 32 @tab Einen ODBC 1.0 Treiber simulieren.
@item 64 @tab Die Angabe 'datenbank' in 'datenbank.tabelle.spalte' ignorieren.
@item 128 @tab Die Verwendung von ODBC-Manager-Zeigern erzwingen (experimentell).
@item 256 @tab Die Verwendung des erweiterten 'fetch' verbieten (experimentell).
@item 512 @tab CHAR-Felder bis zur vollen Spaltenlänge füllen.
@item 1024 @tab SQLDescribeCol() wird voll qualifizierte Spaltennamen zurückgeben.
@item 2048 @tab Verwendet das komprimierte Client-/Server Protokoll.
@item 4096 @tab Weist den Server an, Leerzeichen nach einem Funktionsnamen und vor @code{'('} zu ignorieren (wird von PowerBuilder benötigt). So werden alle Funktionsnamen zu Schlüsselwörtern!
@item 8192 @tab Über "Named Pipes" zu einem @code{mysqld}-Server verbinden, der unter Windows NT läuft.
@item 16384 @tab Ändert LONGLONG-Spalten zu INT-Spalten (einige Applikationen können mit LONGLONG nicht umgehen).
@item 32768 @tab Gibt 'user' als Tabellenqualifizierer und Tabellen-Besitzer von SQL-Tabellen zurück (experimentell).
@item 65536 @tab Liest die Parameter @code{client} und @code{odbc}-Gruppen aus der @file{my.cnf}-Datei.
@item 131072 @tab Fügt einige Sicherheitsüberprüfungen hinzu (sollte nicht nötig sein, aber ...).
@end multitable

Wenn Sie viele Optionen haben wollen, sollten Sie die obigen Flags
hinzufügen. Zum Beispiel gibt Ihnen die Option 12 (4+8) Debugging und keine
Paketbeschränkungen.

Die Standard-@file{MYODBC.DLL}-Datei wird für optimale Performance
kompiliert. Wenn Sie @strong{MyODBC} debuggen wollen (um zum Beispiel
"tracing" zu aktivieren), sollten Sie stattdessen @code{MYODBCD.DLL}
verwenden. Um diese Datei zu installieren, kopieren Sie @file{MYODBCD.DLL}
einfach über die installierte @code{MYODBC.DLL}-Datei.


@node ODBC Problems, MyODBC clients, MyODBC connect parameters, ODBC
@c German node ODBC-Probleme
@subsection Wie Sie Probleme mit MyODBC berichten

@strong{MyODBC} wurde mit Access, Admndemo.exe, C++-Builder,
Borland Builder 4, Centura Team Developer (vorher Gupta SQL/Windows),
ColdFusion (unter Solaris und NT mit Service Pack 5), Crystal Reports,
DataJunction, Delphi, ERwin, Excel, iHTML, FileMaker Pro, FoxPro, Notes
4.5/4.6, SBSS, Perl DBD-ODBC, Paradox, Powerbuilder, Powerdesigner 32
bit, VC++ und Visual Basic getestet.

Wenn Sie weitere Applikationen kennen, die mit @strong{MyODBC}
zusammenarbeiten, sagen Sie uns bitte unter @email{myodbc@@lists.mysql.com}
Bescheid!

Mit einigen Programmen können Fehler wie diese auftreten: @code{Another
user hat modifies the record that you have modified}. Meistens lösen Sie
das folgendermaßen:

@itemize @bullet
@item
Fügen Sie der Tabelle einen Primärschlüssel hinzu, wenn noch keiner
existiert.
@item
Fügen Sie eine TIMESTAMP-Spalte hinzu, wenn noch keine existiert.
@item
Verwenden Sie ausschließlich 'Double Float'-Felder. Manche Programme
kommen mit 'Single Float'-Feldern nicht klar.
@end itemize

Wenn das nicht helfen sollte, dann erstellen Sie eine @code{MyODBC}
'Trace'-Datei und versuchen Sie, die Fehlerquelle so zu erschließen.


@node MyODBC clients, ODBC and last_insert_id, ODBC Problems, ODBC
@c German node MyODBC-Clients
@subsection Programme, die bekanntermaßen mit MyODBC zusammenarbeiten

Die meisten Programme sollten mit @strong{MyODBC} zusammenarbeiten. Für die
unten aufgeführten haben wir es selbst getestet oder haben die Bestätigung
eines Benutzers, dass es läuft.

@table @asis
@item @strong{Programm}
@strong{Anmerkung}
@cindex Microsoft Access

@item Access
Um Access zum Laufen zu bringen:
@itemize @bullet
@item
Wenn Sie Access 2000 verwenden, sollten Sie die neuesten (Version 2.6 oder
höher) Microsoft-MDAC (@code{Microsoft Data Access Components}) von
@uref{http://www.microsoft.com/data} herunterladen. Dies wird folgenden Bug
in Access beheben: Wenn Sie Daten nach MySQL exportieren, werden Tabellen-
und Spaltennamen nicht spezifiziert. Ein anderer Weg, diesen Bug zu
umgehen, ist, MyODBC auf Version 2.50.33 und MySQL auf Version 3.23.x zu
aktualisieren, welche beide zusammen einen Workaround für diesen Bug
implementiert haben.

Ausserdem sollten Sie das Microsoft-Jet-4.0-Service-Pack 5 (SP5)
einspielen, welches hier
@uref{http://support.microsoft.com/support/kb/articles/Q 239/1/14.ASP}
gefunden werden kann. Dies behebt einige Fälle, in denen Spalten als
@code{#deleted#} in Access markiert sind.

Beachten Sie, dass Sie, wenn Sie die MySQL-Version 3.22 verwenden, den
MDAC-Patch einspielen und MyODBC 2.50.32 oder 2.50.34 und höher benutzen
müssen, um dieses Problem zu umgehen.
@item
Für alle Access-Versionen sollten Sie die MyODBC-Optionen auf @code{Return
matching rows} setzen. Für Access 2.0 sollten Sie ausserdem @code{Simulate
ODBC 1.0} einschalten.
@item
Sie sollten einen Timestamp in alle Tabellen einfügen, die Sie
aktualisieren wollen. Für maximale Portablilität werden
@code{TIMESTAMP(14)} oder einfach  @code{TIMESTAMP} anstelle von
@code{TIMESTAMP(X)}-Variationen empfohlen.
@item
Sie sollten einen Primärschlüssel in Ihren Tabellen haben. Falls nicht,
können neue oder geänderte Zeilen als @code{#DELETED#} erscheinen.
@item
Verwenden sie ausschließlich @code{DOUBLE}-Float-Felder. Access kann nicht
richtig mit "Single Floats" vergleichen. Die Symptome sind, dass entweder
neue oder geänderte Zeilen als @code{#DELETED#} erscheinen oder Sie keine
Zeilen finden oder ändern können.
@item
Wenn Sie eine Tabelle mit MyODBC verbinden, die eine @code{BIGINT}-Spalte hat,
werden die Ergebnisse als @code{#DELETED} angezeigt. Sie umgehen das Problem
folgendermaßen:
@itemize @bullet
@item
Fügen Sie eine weitere @code{TIMESTAMP}-"Dummy-Spalte" hinzu, am besten
@code{TIMESTAMP(14)}.
@item
Wählen Sie @code{'BIGINT Spalten zu INT wandeln'} im Verbindungsdialog des
ODBC-DSN-Administrators.
@item
Entfernen Sie die Tabellenverknüpfung aus Access und stellen Sie sie wieder
her.
@end itemize

Die vorherigen Zeilen werden weiterhin als @code{#DELETED#} angezeigt, aber
neue/geänderte Zeilen werden korrekt dargestellt.
@item
Wenn Sie weiterhin den Fehler @code{Ein anderer Benutzer hat Ihre Daten geändert}
erhalten, nachdem Sie die @code{TIMESTAMP}-Spalte hinzugefügt haben, könnte
Ihnen der folgende Trick helfen:

Verwenden Sie anstelle von @code{Datenblattansicht} ein Formular mit den
von Ihnen gewünschten Feldern und benutzen Sie dann
@code{Formularblattansicht}. Sie sollten den @code{StandardWert} für die
@code{TIMESTAMP}-Spalte auf @code{NOW()} setzen. Zusätzlich ist es sicher
nützlich, die @code{TIMESTAMP}-Spalte zu verstecken, damit Ihre Anwender
nicht erschrecken.
@item
Manchmal erstellt Access ungültige SQL-Anfragen, die MySQL nicht versteht.


Wählen Sie zur Lösung dieses Problems
@code{"Abfrage|SQL-spezifisch|Pass-Through"} aus dem Access-Menü.
@item
Wenn Sie statt dessen @code{MEMO}-Spalten haben wollen, sollten Sie die
Spalte mit @code{ALTER TABLE} in @code{TEXT} ändern.
@item
Access kann nicht immer sauber mit @code{DATE}-Spalten umgehen. Wenn Sie ein 
solches Problem haben, ändern Sie die entsprechenden Spalten in @code{DATETIME}.
@item
Wenn Sie in Access eine Spalte @code{BYTE} haben, wird Access versuchen,
diese in @code{TINYINT} anstelle von @code{TINYINT UNSIGNED} zu
exportieren. Das führt zu Problemen, wenn Sie Werte in der Spalte haben,
die größer als 127 sind!
@end itemize

@cindex ADO program
@item ADO
Wenn Sie mit der ADO-API und @strong{MyODBC} kodieren, müssen Sie auf
einige vorgabemäßige Eigenschaften achten, die vom MySQL-Server nicht
unterstützt werden. Die Benutzung von @code{CursorLocationProperty} als
@code{adUseServer} zum Beispiel gibt für @code{RecordCountProperty} ein
Ergebnis von -1 zurück. Um den richtigen Wert zu erhalten, müssen Sie diese
Eigenschaft auf @code{adUseClient} setzen, wie im unten stehenden
Visual-Basic-Code gezeigt:

@example
Dim myconn As New ADODB.Connection
Dim myrs As New Recordset
Dim mySQL As String
Dim myrows As Long

myconn.Open "DSN=MyODBCsample"
mySQL = "SELECT * from user"
myrs.Source = mySQL
Set myrs.ActiveConnection = myconn
myrs.CursorLocation = adUseClient
myrs.Open
myrows = myrs.RecordCount

myrs.Close
myconn.Close
@end example

Ein weiterer Workaround besteht darin, ein @code{SELECT COUNT(*)}-Statement
für eine ähnliche Anfrage zu benutzen, um das korrekte Zählen der Zeilen zu
erreichen.

@item Active server pages (ASP)
Sie sollten den Option-Flag @code{Return matching rows} benutzen.

@item BDE-Applikationen
Damit diese funktionieren, sollten Sie die Option-Flags
@code{Don't optimize column widths} und @code{Return matching rows}
benutzen.

@cindex Borland Builder 4
@item Borland Builder 4
Wenn Sie eine Anfrage starten, können Sie die Eigenschaft @code{Active}
oder die Methode @code{Open} benutzen. Beachten Sie, dass @code{Active}
automatisch mit einer @code{SELECT * FROM ...}-Anfrage startet, was keine
gute Idee ist, wenn Ihre Tabellen Groß sind!
@item ColdFusion (unter Unix)
Die folgenden Informationen sind der ColdFusion-Dokumentation entnommen:

Lesen Sie folgende Informationen, um den ColdFusion-Server für Linux so zu
konfigurieren, dass er den unixODBC-Treiber bei @strong{MyODBC} für
MySQL-Datenquellen benutzt. Allaire kann bestätigen, dass die
@strong{MyODBC}-Version 2.50.26 mit MySQL-Version 3.22.27 und ColdFusion
für Linux funktioniert. (Jede neuere Version sollte ebenfalls
funktionieren.) Sie können @strong{MyODBC} von
@uref{http://www.mysql.com/downloads/api-myodbc.html} herunter laden.

@cindex ColdFusion
Bei ColdFusion Version 4.5.1 können Sie den ColdFusion Administrator
benutzen, um die MySQL-Datenquelle hinzuzufügen. Der Treiber liegt der
ColdFusion Version 4.5.1 jedoch nicht bei. Bevor der MySQL-Treiber in der
Auswahlliste der ODBC-Datenquellen erscheint, müssen Sie den
@strong{MyODBC}-Treiber bauen und nach
@file{/opt/coldfusion/lib/libmyodbc.so} kopieren.

Das Contrib-Verzeichnis enthält das Programm mydsn-xxx.zip, mit dem Sie die
DSN-Registrierungs-Datei für den MyODBC-Treiber auf
Coldfusion-Applikationen bauen können.

@cindex DataJunction
@item DataJunction
Sie müssen es ändern, damit es @code{VARCHAR} statt @code{ENUM} ausgibt,
weil es Letzteres in einer Art ausgibt, die MySQL nicht versteht.

@cindex Excel
@item Excel
Funktioniert. Einige Tipps:
@itemize @bullet
@item
Wenn Sie Probleme mit Datumsangaben haben, versuchen Sie, sie als
Zeichenketten mit der @code{CONCAT()}-Funktion abzurufen. Beispiel:
@example
select CONCAT(sonnenaufgang), CONCAT(sonnenuntergang)
    from aufgang_untergang;
@end example
Werte, die auf diese Art als Zeichenketten abgerufen werden, sollten
korrekt als Zeitwerte von Excel97 erkannt werden.

Der Zweck von @code{CONCAT()} in diesem Beispiel ist, ODBC auszutricksen,
so dass es denkt, dass die Spalte vom Typ "Zeichenkette" sei. Ohne
@code{CONCAT()} weiß ODBC, dass die Spalte vom Typ "Zeit" ist, und Excel
versteht das nicht.

Beachten Sie, dass das ein Bug in Excel ist, weil es eine Zeichenkette
automatisch in eine Zeitangabe umwandelt. Das wäre sehr gut, wenn die
Quelle eine Textdatei wäre, ist aber einfach nur dumm, wenn die Quelle eine
ODBC-Verbindung ist, die exakte Typen für jede Spalte übermittelt.
@end itemize
@cindex Word
@item Word

Um Daten von MySQL in Word- / Excel-Dokumente abzurufen, müssen Sie den
@code{MyODBC}-Treiber benutzen und das Add-in Microsoft Query hinzufügen.

Erzeugen Sie zum Beispiel eine Datenbank mit einer Tabelle, die 2
Text-Spalten enthält:

@itemize @bullet
@item
Fügen Sie Zeilen mit dem @code{mysql}-Kommandozeilenwerkzeug ein.
@item
Erzeugen Sie eine DSN-Datei mit dem MyODBC-Treiber, die Sie zum Beispiel my
nennen, für die oben genannten Datenbank.
@item
Öffnen Sie Word.
@item
Erzeugen Sie ein leeres Dokument.
@item
Öffnen Sie die Symbolleiste 'Datenbank' und klicken Sie auf die
Schaltfläche 'Datenbank einfügen'.
@item
Klicken Sie auf die Schaltfläche 'Daten abrufen'.
@item
Klicken Sie auf die Schaltfläche 'MS Query'.
@item
Erzeugen Sie in MS Query eine neue Datenquelle unter Benutzung der
DSN-Datei my.
@item
Wählen Sie die neue Anfrage aus.
@item
Wählen Sie die Spalten aus, die Sie haben wollen.
@item
Legen Sie bei Bedarf einen Filter fest.
@item
Legen Sie bei Bedarf eine Sortierung fest.
@item
Wählen Sie 'Daten an Word zurückgeben'.
@item
Klicken Sie auf 'Beenden'.
@item
Klicken Sie auf 'Daten einfügen' und wählen Sie die Datensätze aus.
@item
Klicken Sie auf 'OK', und Sie sehen die Zeilen in Ihrem Word-Dokument.
@end itemize

@cindex odbcadmin
@item odbcadmin
Test-Programm für ODBC.
@cindex Delphi-Programm
@item Delphi
Sie müssen BDE-Version 3.2 oder neuer benutzen. Setzen Sie die `Don't
optimize column width'-Option, wenn Sie sich mit MySQL verbinden.

Hier ist möglicherweise nützlicher Delphi-Code, der sowohl einen
ODBC-Eintrag als auch einen BDE-Eintrag für @strong{MyODBC} setzt (der
BDE-Eintrag erfordert einen BDE-Alias-Editor, der kostenlos auf einer
Delphi Super Page in Ihrer Nähe herunter geladen werden kann (Dank dafür an
Bryan Brunton @email{bryan@@flesherfab.com}:

@example
fReg:= TRegistry.Create;
  fReg.OpenKey('\Software\ODBC\ODBC.INI\DocumentsFab', True);
  fReg.WriteString('Database', 'Documents');
  fReg.WriteString('Description', ' ');
  fReg.WriteString('Driver', 'C:\WINNT\System32\myodbc.dll');
  fReg.WriteString('Flag', '1');
  fReg.WriteString('Password', '');
  fReg.WriteString('Port', ' ');
  fReg.WriteString('Server', 'xmark');
  fReg.WriteString('User', 'winuser');
  fReg.OpenKey('\Software\ODBC\ODBC.INI\ODBC Data Sources', True);
  fReg.WriteString('DocumentsFab', 'MySQL');
  fReg.CloseKey;
  fReg.Free;

  Memo1.Lines.Add('DATABASE NAME=');
  Memo1.Lines.Add('USER NAME=');
  Memo1.Lines.Add('ODBC DSN=DocumentsFab');
  Memo1.Lines.Add('OPEN MODE=READ/WRITE');
  Memo1.Lines.Add('BATCH COUNT=200');
  Memo1.Lines.Add('LANGTreiber=');
  Memo1.Lines.Add('MAX ROWS=-1');
  Memo1.Lines.Add('SCHEMA CACHE DIR=');
  Memo1.Lines.Add('SCHEMA CACHE SIZE=8');
  Memo1.Lines.Add('SCHEMA CACHE TIME=-1');
  Memo1.Lines.Add('SQLPASSTHRU MODE=SHARED AUTOCOMMIT');
  Memo1.Lines.Add('SQLQRYMODE=');
  Memo1.Lines.Add('ENABLE SCHEMA CACHE=FALSE');
  Memo1.Lines.Add('ENABLE BCD=FALSE');
  Memo1.Lines.Add('ROWSET SIZE=20');
  Memo1.Lines.Add('BLOBS TO CACHE=64');
  Memo1.Lines.Add('BLOB SIZE=32');

  AliasEditor.Add('DocumentsFab','MySQL',Memo1.Lines);
@end example

@cindex C++-Builder
@item C++-Builder
Getestet mit BDE-Version 3.0. Das einzige bekannte Problem ist, dass
Anfragefelder nicht aktualisiert werden, wenn sich die Tabellenstruktur
ändert. BDE scheint jedoch keine Primärschlüssel zu erkennen, sondern nur
den Index PRIMARY, obwohl das eigentlich kein Problem darstellt.

@item Vision
Sie sollten den Option-Flag @code{Return matching rows} benutzen.

@cindex Visual Basic
@item Visual Basic
Damit Sie eine Tabelle aktualisieren können, müssen Sie für die Tabelle
einen Primärschlüssel definieren.

Visual Basic mit ADO kann keine großen Ganzzahlen handhaben. Das heißt,
dass einige Anfragen wie @code{SHOW PROCESSLIST} nicht korrekt
funktionieren. Das läßt sich beheben, indem man die Option
@code{OPTION=16834} in der ODBC-Verbindungs-Zeichenkette hinzufügt oder die
@code{Change BIGINT columns to INT}-Option im MySQL-Verbindungsbildschirm
setzt. Eventuell sollten Sie auch die @code{Return matching rows}-Option
setzen.

@item VisualInterDev
Wenn Sie den Fehler @code{[Microsoft][ODBC Driver Manager] Driver does not
support this parameter} erhalten, kann es daran liegen, dass Sie ein
@code{BIGINT} in Ihrem Ergebnis haben. Versuchen Sie, die @code{Change
BIGINT columns to INT}-Option im MySQL-Verbindungsbildschirm zu setzen.

@item Visual Objects
Sie sollten den Option-Flag @code{Don't optimize column widths} setzen.
@end table


@node ODBC and last_insert_id, MyODBC bug report, MyODBC clients, ODBC
@c German node ODBC und last_insert_id
@subsection Wie man den Wert einer @code{AUTO_INCREMENT}-Spalte in ODBC erhält

@cindex AUTO-INCREMENT, ODBC

Ein häufiges Problem ist es, den Wert einer automatisch erzeugten Kennung
von einem @code{INSERT} zu erhalten. Bei ODBC können Sie etwas wie
folgendes tun (unter der Annahme, dass @code{auto} ein
@code{AUTO_INCREMENT}-Feld ist):

@example
INSERT INTO foo (auto,text) VALUES(NULL,'text');
SELECT LAST_INSERT_ID();
@end example

Oder, wenn Sie die Kennung in eine andere Tabelle einfügen wollen:

@example
INSERT INTO foo (auto,text) VALUES(NULL,'text');
INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text');
@end example

@xref{Getting unique ID}.

Bei einigen ODBC-Applikationen (zumindest Delphi und Access) kann folgende
Anfrage benutzt werden, um eine neu eingefügte Zeile zu finden:
@example
SELECT * FROM tabelle WHERE auto IS NULL;
@end example


@node MyODBC bug report,  , ODBC and last_insert_id, ODBC
@c German node MyODBC-Bug-Bericht
@subsection Probleme mit MyODBC berichten

@cindex berichten, MyODBC-Probleme
@cindex Probleme, ODBC
@cindex MyODBC, Probleme berichten

Wenn Sie Probleme mit @strong{MyODBC} bekommen, sollten Sie als erstes eine
Log-Datei durch den ODBC-Manager anlegen lassen (das Log, das Sie erhalten,
wenn Sie Logs von ODBCADMIN abfragen) sowie ein @strong{MyODBC}-Log.

Um ein @strong{MyODBC}-Log zu erhalten, tun Sie folgendes:

@enumerate
@item
Stellen Sie sicher, dass Sie @code{myodbcd.dll} und nicht @code{myodbc.dll}
benutzen. Am einfachsten ist es, wenn Sie sich @code{myodbcd.dll} aus der
MyODBC-Distribution holen und es über @code{myodbc.dll} kopieren, die sich
wahrscheinlich in Ihrem @code{C:\windows\system32}- oder
@code{C:\winnt\system32}-Verzeichnis befindet.

Denken Sie daran, dass Sie wahrscheinlich die alten myodbc.dll nach dem
Testen wiederherstellen wollen, weil Sie um einiges schneller ist als
@code{myodbcd.dll}.
@item
Kreuzen Sie `Trace MyODBC' im @strong{MyODBC}-Verbindungs- bzw.
Konfigurationsfenster an. Das Log wird in die Datei @file{C:\myodbc.log}
geschrieben.

Wenn Sie zu diesem Fenster zurückkehren und feststellen, dass die
Trace-Option nicht mehr angekreuzt ist, heißt das, dass Sie nicht den
@code{myodbcd.dll}-Treiber benutzen (siehe oben).
@item
Starten Sie Ihre Applikation und versuchen Sie, eine Fehlfunktion zu
bekommen.
@end enumerate

Untersuchen Sie die @code{MyODBC-Trace-Datei}, um herauszufinden, was
möglicherweise schief geht. Sie können die abgesetzten Anfragen finden,
indem Sie nach der Zeichenkette @code{>mysql_real_query} in der
@file{myodbc.log}-Datei suchen.

Sie sollten die Anfragen auch zusätzlich im @code{mysql}-Monitor oder in
@code{admndemo} laufen lassen, um herauszufinden, ob der Fehler bei MyODBC
oder bei MySQL liegt.

Wenn Sie herausgefunden haben, was schief läuft, schicken Sie bitte nur die
relevanten Zeilen (maximal 40 Zeilen) an @email{myodbc@@lists.mysql.com}.
Bitte schicken Sie nie die gesamte MyODBC- oder ODBC-Log-Datei!

Wenn Sie nicht herausfinden können, was schief läuft, besteht die letzte
Option darin, eine Archivdatei anzulegen (tar oder zip), die eine
MyODBC-Trace-Datei, die ODBC-Log-Datei und eine README-Datei enthält, die
das Problem erläutert. Schicken Sie diese an
@uref{ftp://support.mysql.com/pub/mysql/secret}. Nur wir bei MySQL AB haben
Zugriff auf die Dateien, die Sie hochspielen, und wir gehen mit den Daten
sehr diskret um!

Wenn Sie ein Programm erzeugen können, das dieses Problem ebenfalls zeigt,
laden Sie dieses bitte ebenfalls hoch!

Wenn das Programm mit irgend einem anderen SQL-Server funktioniert, sollten
Sie eine ODBC-Log-Datei anlegen, in der Sie dasselbe in dem anderen
SQL-Server ausführen.

Bedenken Sie, dass wir umso eher das Problem beheben können, desto mehr
Informationen Sie uns zur Verfügung stellen!


@node C, Cplusplus, ODBC, Clients
@c German node C
@section MySQL-C-API

@cindex C-API, datatypes
@cindex Datentypen, C-API


Der C-API-Code wird mit MySQL ausgeliefert. Er ist in der
@code{mysqlclient}-Bibliothek enthalten und erlaubt C-Programmen, auf eine
Datenbank zuzugreifen.

Viele Clients in der MySQL-Quelldistribution sind in C geschrieben. Wenn
Sie nach Beispielen für den Gebrauch der C-API suchen, schauen Sie sich
diese Clients an. Sie finden Sie im @code{clients}-Verzeichnis in der
MySQL-Quelldistribution.

Viele andere Client-APIs (alle ausser Java) benutzen die
@code{mysqlclient}-Bibliothek, um mit dem MySQL-Server zu kommunizieren.
Das heißt zum Beispiel, dass Sie viele derselben Umgebungsvariablen nutzen
können, die von anderen Client-Programmen benutzt werden, weil sie von der
Bibliothek referenziert werden. Eine Liste dieser Variablen findet sich
unter @ref{Client-Side Scripts}.

Der Client hat eine maximale Kommunikationspuffergröße. Die anfänglich
zugewiesene Puffergröße (16 KB) wird automatisch bis zur maximale Größe
(16 MB) vergrößert. Weil Puffergrößen nur bei Bedarf vergrößert werden,
bedeutet die einfache Erhöhung der maximalen Größe nicht per se, dass mehr
Ressourcen benutzt werden. Die Überprüfung der Größe ist hauptsächlich
eine Prüfung auf irrtümliche Anfragen und Kommunikationspakete.

Der Kommunikationspuffer muss Groß genug sein, um ein einzelnes
SQL-Statement aufzunehmen (für den Client-Server-Verkehr) und eine Zeile
zurückgegebener Daten (für den Server-Client-Verkehr). Der
Kommunikationspuffer jedes Threads wird dynamisch vergrößert, um jede
Anfrage oder Zeile bis zur maximalen Größe zu handhaben. Wenn Sie
beispielsweise @code{BLOB}-Werte haben, die bis zu 16 MB an Daten
beinhalten, müssen Sie eine Kommunikationspuffergrenze von zumindest 16 MB
haben (sowohl beim Server als auch beim Client). Die vorgabemäßige
maximale Größe beim Client liegt bei 16 MB, aber die vorgabemäßige
maximale Grenze beim Server liegt bei 1 MB. Das können Sie vergrößern,
indem Sie den Wert des @code{max_allowed_packet}-Parameters setzen, wenn
der Server gestartet wird. @xref{Server parameters}.

Der MySQL-Server verringert den Kommunikationspuffer auf
@code{net_buffer_length} Bytes nach jeder Anfrage. Bei Clients wird die
Größe des zugewiesenen Puffers bei einer Verbindung nicht herabgesetzt,
bis die Verbindung geschlossen wird. Dann wird der Client-Speicher wieder
freigesetzt.

Zum Programmieren mit Threads siehe @ref{Threaded clients}. Um eine
Standalone-Applikation herzustellen, die "Server" und "Client" im selben
Programm beinhaltet (und nicht mit einem externen MySQL-Server
kommuniziert), siehe @ref{libmysqld}.


@menu
* C API datatypes::             
* C API function overview::     
* C API functions::             
* C Thread functions::          
* C Embedded Server func::      
* C API problems::              
* Building clients::            
* Threaded clients::            
* libmysqld::                   
@end menu

@node C API datatypes, C API function overview, C, C
@c German node C-API-Datentypen
@subsection C-API-Datentypen

@table @code
@tindex MYSQL C type
@item MYSQL
This structure represents a handle to one Datenbank connection. It is
used für almost all MySQL Funktionen.

@tindex MYSQL_RES C-Typ
@item MYSQL_RES
Diese Struktur repräsentiert das Ergebnis einer Anfrage, die Zeilen
zurückgibt (@code{SELECT}, @code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}).
Die von der Anfrage zurückgegebene Informationen wird im Weiteren
@emph{result set} (Ergebnismenge) genannt.

@tindex MYSQL_ROW C-Typ
@item MYSQL_ROW
Das ist eine Typ-sichere Repräsentation einer Zeile von Daten. Momentan ist
sie als ein Array gezählter Byte-Zeichenketten implementiert. (Sie können
diese nicht als NULL-begrenzte Zeichenketten behandeln, falls Feldwert
binäre Daten enthalten können, welche solche Werte intern NULL-Bytes
enthalten können.) Zeilen werden mit dem Aufruf von
@code{mysql_fetch_row()} abgeholt.

@tindex MYSQL_FIELD C-Typ
@item MYSQL_FIELD
Diese Struktur enthält Informationen über ein Feld, wie Feldname, Feldtyp
und Feldgröße. Seine Elemente werden weiter unten genauer beschrieben. Sie
erhalten die @code{MYSQL_FIELD}-Strukturen für jedes Feld durch den
wiederholten Aufruf von @code{mysql_fetch_field()}. Feldwerte sind nicht
Teil dieser Struktur, sondern in der @code{MYSQL_ROW}-Struktur enthalten.


@tindex MYSQL_FIELD_OFFSET C-Typ
@item MYSQL_FIELD_OFFSET
Das ist eine Typ-sichere Repräsentation eines Offsets in einer
MySQL-Feldliste (benutzt von @code{mysql_field_seek()}.) Offsets sind
Feldnummern innerhalb einer Zeile, beginnend mit 0.

@tindex my_ulonglong C-Typ
@tindex my_ulonglong-Werte, Ausgabe
@item my_ulonglong
Der Typ, der für die Anzahl von Zeilen und für @code{mysql_affected_rows()},
@code{mysql_num_rows()}, und @code{mysql_insert_id()} benutzt wird. Dieser
Typ stellt einen Bereich von @code{0} bis @code{1.84e19} zur Verfügung.

Auf manchen Systemen funktioniert der Versuch, einen Wert des Typs
@code{my_ulonglong} auszugeben, nicht. Um einen solchen Wert auszugeben,
wandeln Sie ihn in @code{unsigned long} um und benutzen Sie ein
@code{%lu}-Ausgabeformat. Beispiel:
@example
printf (Anzahl von Zeilen: %lu\n", (unsigned long) mysql_num_rows(result));
@end example
@end table

@noindent
Die @code{MYSQL_FIELD}-Struktur enthält die unten aufgeführten Elemente:

@table @code
@item char * name
Der Name des Feldes, als NULL-begrenzte Zeichenkette.

@item char * table
Der Name der Tabelle, die dieses Feld enthält, falls es kein berechnetes
Feld ist. Bei berechneten Feldern ist der @code{table}-Wert eine leere
Zeichenkette.

@item char * def
Der Vorgabewert dieses Felds als eine NULL-begrenzte Zeichenkette. Dieser
wird nur gesetzt, wenn Sie @code{mysql_list_fields()} benutzen.

@item enum enum_field_types-Typ
Der Typ des Felds. Der @code{type}-Wert kann einer der folgenden sein:

@multitable @columnfractions .3 .55
@item @strong{Typwert}                  @tab @strong{Typbedeutung}
@item @code{FIELD_TYPE_TINY}            @tab @code{TINYINT}-Feld
@item @code{FIELD_TYPE_SHORT}           @tab @code{SMALLINT}-Feld
@item @code{FIELD_TYPE_LONG}            @tab @code{INTEGER}-Feld
@item @code{FIELD_TYPE_INT24}           @tab @code{MEDIUMINT}-Feld
@item @code{FIELD_TYPE_LONGLONG}        @tab @code{BIGINT}-Feld
@item @code{FIELD_TYPE_DECIMAL}         @tab @code{DECIMAL}- oder @code{NUMERIC}-Feld
@item @code{FIELD_TYPE_FLOAT}           @tab @code{FLOAT}-Feld
@item @code{FIELD_TYPE_DOUBLE}          @tab @code{DOUBLE}- oder @code{REAL}-Feld
@item @code{FIELD_TYPE_TIMESTAMP}       @tab @code{TIMESTAMP}-Feld
@item @code{FIELD_TYPE_DATE}            @tab @code{DATE}-Feld
@item @code{FIELD_TYPE_TIME}            @tab @code{TIME}-Feld
@item @code{FIELD_TYPE_DATETIME}        @tab @code{DATETIME}-Feld
@item @code{FIELD_TYPE_YEAR}            @tab @code{YEAR}-Feld
@item @code{FIELD_TYPE_STRING}          @tab @code{CHAR}- oder @code{VARCHAR}-Feld
@item @code{FIELD_TYPE_BLOB}            @tab @code{BLOB}- oder @code{TEXT}-Feld (benutzen Sie @code{max_length}, um die maximale Länge festzulegen)
@item @code{FIELD_TYPE_SET}             @tab @code{SET}-Feld
@item @code{FIELD_TYPE_ENUM}            @tab @code{ENUM}-Feld
@item @code{FIELD_TYPE_NULL}            @tab @code{NULL}-Feld
@item @code{FIELD_TYPE_CHAR}            @tab Veraltet; benutzen Sie statt dessen @code{FIELD_TYPE_TINY}
@end multitable

Sie können das @code{IS_NUM()}-Makro benutzen, um zu testen, ob ein Feld
einen numerischen Typ besitzt oder nicht. Übergeben Sie den
@code{type}-Wert an @code{IS_NUM()}, und Sie erhalten WAHR (true), wenn das
Feld numerisch ist:

@example
if (IS_NUM(field->type))
    printf("Feld ist numerisch\n");
@end example

@item unsigned int length
Die Breite des Felds, wie in der Tabellendefinition festgelegt.

@item unsigned int max_length
Die maximale Breite des Felds für die Ergebnismenge (die Länge des längsten
Feldwerts für die Zeilen, die tatsächlich in der Ergebnismenge enthalten
sind). Wenn Sie @code{mysql_store_result()} oder @code{mysql_list_fields()}
benutzen, enthält die Variable die maximale Länge für das Feld. Wenn Sie
@code{mysql_use_result()} benutzen, ist sie 0.

@item unsigned int flags
Unterschiedliche Bit-Flags für das Feld. Der @code{flags}-Wert kann 0 oder
mehr der folgenden Bits gesetzt haben:

@multitable @columnfractions .3 .55
@item @strong{Flag-Wert}         @tab @strong{Flag-Bedeutung}
@item @code{NOT_NULL_FLAG}       @tab Feld darf nicht @code{NULL} sein
@item @code{PRI_KEY_FLAG}        @tab Feld ist Teil eines Primärschlüssels
@item @code{UNIQUE_KEY_FLAG}     @tab Feld ist Teil eines eindeutigen Schlüssels
@item @code{MULTIPLE_KEY_FLAG}   @tab Feld ist Teil eines nicht eindeutigen Schlüssels
@item @code{UNSIGNED_FLAG}       @tab Feld hat das @code{UNSIGNED}-Attribute
@item @code{ZEROFILL_FLAG}       @tab Feld hat das @code{ZEROFILL}-Attribute
@item @code{BINARY_FLAG}         @tab Feld hat das @code{BINARY}-Attribute
@item @code{AUTO_INCREMENT_FLAG} @tab Feld hat das @code{AUTO_INCREMENT}-Attribut
@item @code{ENUM_FLAG}           @tab Feld ist ein @code{ENUM} (veraltet)
@item @code{BLOB_FLAG}           @tab Feld ist ein @code{BLOB} oder @code{TEXT} (veraltet)
@item @code{TIMESTAMP_FLAG}      @tab Feld ist ein @code{TIMESTAMP} (veraltet)
@end multitable

Die Benutzung der @code{BLOB_FLAG}-, @code{ENUM_FLAG}- und
@code{TIMESTAMP_FLAG}-Flags ist veraltet, weil sie den Feldtyp statt eines
Attributs seines Typs angeben. Statt dessen sollten Sie @code{field->type}
gegen @code{FIELD_TYPE_BLOB}, @code{FIELD_TYPE_ENUM} oder
@code{FIELD_TYPE_TIMESTAMP} testen.

@noindent
Das unten stehende Beispiel zeigt eine typische Benutzung des
@code{flags}-Werts:

@example
if (field->flags & NOT_NULL_FLAG)
    printf("Feld darf nicht NULL sein\n");
@end example

Sie können aus Bequemlichkeitsgründen folgende Makros benutzen, um den
Bool'schen Status des @code{flags}-Werts zu bestimmen:

@multitable @columnfractions .3 .5
@item @code{IS_NOT_NULL(flags)} @tab WAHR, wenn der Feldwert als @code{NOT NULL} definiert ist
@item @code{IS_PRI_KEY(flags)}  @tab WAHR, wenn der Feldwert ein Primärschlüssel ist
@item @code{IS_BLOB(flags)}     @tab WAHR, wenn der Feldwert ein @code{BLOB} oder @code{TEXT} ist (veraltet; testen Sie statt dessen @code{field->type})
@end multitable

@item unsigned int decimals
Die Anzahl von Dezimalstellen für numerische Felder.
@end table


@node C API function overview, C API functions, C API datatypes, C
@c German node C-API-Funktionsüberblick
@subsection C-API-Funktionsüberblick

@cindex C-API, Funktionen
@cindex Funktionen, C-API

Die in der C-API verfügbaren Funktionen sind unten aufgeführt und im
nächsten Abschnitt detaillierter beschrieben.
@xref{C API functions}.

@multitable @columnfractions .3 .7
@item @strong{mysql_affected_rows()} @tab
Gibt die Anzahl von Zeilen zurück, die durch die letzte @code{UPDATE}-,
@code{DELETE}- oder @code{INSERT}-Anfrage geändert, gelöscht bzw.
hinzugefügt wurden.

@item @strong{mysql_close()} @tab
Schließt eine Server-Verbindung.

@item @strong{mysql_connect()} @tab
Stellt die Verbindung mit einem MySQL-Server her. Diese Funktion ist
veraltet, benutzen Sie statt dessen @code{mysql_real_connect()}.

@item @strong{mysql_change_user()} @tab
Ändert Benutzer und Datenbank bei einer geöffneten Verbindung.

@item @strong{mysql_character_set_name()} @tab
Gibt den Namen des vorgabemäßigen Zeichensatzes für die Verbindung zurück.

@item @strong{mysql_create_db()} @tab
Erzeugt eine Datenbank. Diese Funktion ist veraltet, benutzen Sie statt
dessen den SQL-Befehl @code{CREATE DATABASE}.

@item @strong{mysql_data_seek()} @tab
Sucht bis zu einer beliebigen Zeile in einer Anfrage-Ergebnismenge.

@item @strong{mysql_debug()} @tab
Macht ein @code{DBUG_PUSH} mit der angegebenen Zeichenkette.

@item @strong{mysql_drop_db()} @tab
Löscht eine Datenbank. Diese Funktion ist veraltet, benutzen Sie statt
dessen den SQL-Befehl @code{DROP DATABASE}.

@item @strong{mysql_dump_debug_info()} @tab
Veranlasst den Server, Debug-Informationen in die Log-Datei zu schreiben.

@item @strong{mysql_eof()} @tab
Stellt fest, ob die letzte Zeile der Ergebnismenge gelesen wurde oder
nicht. Diese Funktion ist veraltet, benutzen Sie statt dessen
@code{mysql_errno()} oder @code{mysql_error()}.

@item @strong{mysql_errno()} @tab
Gibt die Fehlernummer der zuletzt aufgerufenen MySQL-Funktion zurück.

@item @strong{mysql_error()} @tab
Gibt die Fehlermeldung der zuletzt aufgerufenen MySQL-Funktion zurück.

@item @strong{mysql_real_escape_string()} @tab
Escapet Sonderzeichen in einer Zeichenkette, die für ein SQL-Statement
benutzt wird, wobei der aktuelle Zeichensatz der Verbindung berücksichtigt
wird.

@item @strong{mysql_escape_string()} @tab
Escapet Sonderzeichen in einer Zeichenkette, die für ein SQL-Statement
benutzt wird.

@item @strong{mysql_fetch_field()} @tab
Gibt den Typ des nächsten Tabellenfelds zurück.

@item @strong{mysql_fetch_field_direct()} @tab
Gibt den Typ eines Tabellenfelds zurück, angegeben durch eine Feldnummer.

@item @strong{mysql_fetch_fields()} @tab
Gibt ein Array aller Feldstrukturen zurück.

@item @strong{mysql_fetch_lengths()} @tab
Gibt die Länge aller Spalten in der aktuellen Zeile zurück.

@item @strong{mysql_fetch_row()} @tab
Holt die nächste Zeile aus der Ergebnismenge.

@item @strong{mysql_field_seek()} @tab
Setzt den Spaltencursor auf eine bestimmte Spalte.

@item @strong{mysql_field_count()} @tab
Gibt die Anzahl der Ergebnisspalten für die letzte Anfrage zurück.

@item @strong{mysql_field_tell()} @tab
Gibt die Position des Feldcursors zurück, der für das letzte
@code{mysql_fetch_field()} benutzt wurde.

@item @strong{mysql_free_result()} @tab
Gibt Speicher frei, der von einer Ergebnismenge benutzt wird.

@item @strong{mysql_get_client_info()} @tab
Gibt Client-Versionsinformationen zurück.

@item @strong{mysql_get_host_info()} @tab
Gibt eine Zeichenkette zurück, die die Verbindung beschreibt.

@item @strong{mysql_get_proto_info()} @tab
Gibt die Protokollversion zruück, die von der Verbindung benutzt wird.

@item @strong{mysql_get_server_info()} @tab
Gibt die Server-Versionsnummer zurück.

@item @strong{mysql_info()} @tab
Gibt Informationen über die zuletzt ausgeführte Anfrage zurück.

@item @strong{mysql_init()} @tab
Holt oder initialisiert eine @code{MYSQL}-Struktur.

@item @strong{mysql_insert_id()} @tab
Gibt die Kennung zurück, die für eine @code{AUTO_INCREMENT}-Spalte durch
die letzte Anfrage erzeugt wurde.

@item @strong{mysql_kill()} @tab
Tötet einen angegebenen Thread.

@item @strong{mysql_list_dbs()} @tab
Gibt die Datenbanknamen zurück, die mit einem einfachen regulären Ausdruck
übereinstimmen.

@item @strong{mysql_list_fields()} @tab
Gibt die Feldnamen zurück, die mit einem einfachen regulären Ausdruck
übereinstimmen.

@item @strong{mysql_list_processes()} @tab
Gibt eine Liste der aktuellen Server-Threads zurück.

@item @strong{mysql_list_tables()} @tab
Gibt Tabellenamen zurück, die mit einem einfachen regulären Ausdruck
übereinstimmen.

@item @strong{mysql_num_fields()} @tab
Gibt die Anzahl von Spalten in einer Ergebnismenge zurück.

@item @strong{mysql_num_rows()} @tab
Gibt die Anzahl von Zeilen in einer Ergebnismenge zurück.

@item @strong{mysql_options()} @tab
Setzt Verbindungsoptionen für @code{mysql_connect()}.

@item @strong{mysql_ping()} @tab
Prüft, ob die Verbindung zum Server funktioniert oder nicht und verbindet
sich erneut, falls notwendig.

@item @strong{mysql_Anfrage()} @tab
Führt eine SQL-Anfrage aus, die als NULL-begrenzte Zeichenkette angegeben
wird.

@item @strong{mysql_real_connect()} @tab
Verbindet sich mit einem MySQL-Server.

@item @strong{mysql_real_query()} @tab
Führt eine SQL-Anfrage aus, die als gezählte Zeichenkette angegeben wird.

@item @strong{mysql_reload()} @tab
Weist den Server an, die Berechtigungstabellen erneut zu laden.

@item @strong{mysql_row_seek()} @tab
Sucht bis zu einer Zeile in einer Ergebnismenge, indem sie den Wert
benutzt, der von @code{mysql_row_tell()} zurückgegeben wird.

@item @strong{mysql_row_tell()} @tab
Gibt die Zeilencursorposition zurück.

@item @strong{mysql_select_db()} @tab
Wählt eine Datenbank aus.

@item @strong{mysql_shutdown()} @tab
Fährt den Datenbankserver herunter.

@item @strong{mysql_stat()} @tab
Gibt den Serverstatus als Zeichenkette zurück.

@item @strong{mysql_store_result()} @tab
Ruft eine komplette Ergebnismenge zum Client ab.

@item @strong{mysql_thread_id()} @tab
Gibt die aktuelle Thread-Kennung zurück.

@item @strong{mysql_thread_safe()} @tab
Gibt 1 zurück, wenn die Clients Thread-sicher kompiliert sind.

@item @strong{mysql_use_result()} @tab
Initialisiert den zeilenweisen Abruf einer Ergebnismenge.
@end multitable

Um sich mit dem Server zu verbinden, rufen Sie @code{mysql_init()} auf, um
einen Verbindungs-Handler zu initialisieren. Rufen Sie dann
@code{mysql_real_connect()} mit diesem Handler auf (mit Informationen wie
Hostname, Benutzername und Passwort). Beim Verbinden setzt
@code{mysql_real_connect()} den @code{reconnect}-Flag (Teil der
MYSQL-Struktur) auf einen Wert von @code{1}. Dieser Flag legt bei einer
Anfrage, die wegen einer verloren gegangenen Serververbindung nicht
ausgeführt werden kann, fest, dass ein erneutes Verbinden versucht wird,
bevor aufgegeben wird. Wenn Sie mit der Verbindung fertig sind, rufen Sie
@code{mysql_close()} auf, um sie zu beenden.

Während eine Verbindung aktiv ist, kann der Client SQL-Anfragen an den
Server schicken, indem er @code{mysql_query()} oder
@code{mysql_real_query()} benutzt. Der Unterschied zwischen beiden ist,
dass @code{mysql_query()} erwartet, dass die Anfrage als NULL-separierte
Zeichenkette angegeben wird, während @code{mysql_real_query()} eine
gezählte Zeichenkette erwartet. Wenn die Zeichenkette Binärdaten enthält
(was NULL-Bytes beinhalten kann), müssen Sie @code{mysql_real_query()}
benutzen.

Bei jeder Nicht-@code{SELECT}-Anfrage (wie @code{INSERT}, @code{UPDATE},
@code{DELETE}) finden Sie heraus, wie viele Zeilen geändert (betroffen)
wurden, indem Sie @code{mysql_affected_rows()} aufrufen.

Bei @code{SELECT}-Anfragen rufen Sie die ausgewählten Zeilen als
Ergebnismenge ab. (Beachten Sie, dass einige Statements ähnlich wie
@code{SELECT} sind, weil auch sie Zeilen zurückgeben. Das sind @code{SHOW},
@code{DESCRIBE} und @code{EXPLAIN}. Sie werden auf dieselbe Weise behandelt
wie @code{SELECT}-Statements.)

Es gibt für einen Client zwei Möglichkeiten, Ergebnismengen zu verarbeiten.
Eine Möglichkeit besteht darin, die gesamte Ergebnismenge auf einmal
abzurufen, indem @code{mysql_store_result()} aufgerufen wird. Diese
Funktion holt alle Zeilen vom Server ab, die von der Anfrage zurückgegeben
werden, und speichert sie im Client. Die zweite Möglichkeit besteht darin,
dass der Client die Ergebnismenge zeilenweise abruft, indem er
@code{mysql_use_result()} aufruft. Diese Funktion initialisiert den Abruf,
holt aber keinerlei Zeilen vom Server ab.

In beiden Fällen können Sie auf Zeilen zugreifen, indem Sie
@code{mysql_fetch_row()} aufrufen. Bei @code{mysql_store_result()} greift
@code{mysql_fetch_row()} auf Zeilen zurück, die bereits vom Server geholt
wurden. Bei @code{mysql_use_result()} ruft @code{mysql_fetch_row()} die
Zeilen direkt vom Server ab. Informationen über die Größe der Daten in
jeder Zeile sind durch Aufruf von @code{mysql_fetch_lengths()} verfügbar.

Wenn Sie mit einer Ergebnismenge fertig sind, rufen Sie
@code{mysql_free_result()} auf, um den hierfür benutzten Speicher
freizugeben.

Die beiden Abrufmechanismen sind komplementär. Client-Programme sollten
entscheiden, welcher Ansatz der für ihre Erfordernisse geeignetste ist. In
der Praxis wird für Clients häufiger @code{mysql_store_result()} verwendet.

Ein Vorteil von @code{mysql_store_result()} ist, dass bereits alle Zeilen
zum Client geholt wurden. Deshalb können Sie nicht nur sequentiell auf
Zeilen zugreifen, sondern sich in der Ergebnismenge vorwärts und rückwärts
bewegen, indem Sie @code{mysql_data_seek()} oder @code{mysql_row_seek()}
benutzen, um die aktuelle Position innerhalb der Ergebnismenge zu ändern.
Sie können auch herausfinden, wie viele Zeilen es gibt, indem Sie
@code{mysql_num_rows()} aufrufen. Auf der anderen Seite kann der
Speicherbedarf für @code{mysql_store_result()} sehr hoch sein, wenn Sie
große Ergebnismengen abrufen, so dass Speichermangel eintreten kann.

Ein Vorteil von @code{mysql_use_result()} ist, dass der Client weniger
Arbeitsspeicher für die Ergebnismenge benötigt, weil er nur eine Zeile
zugleich erhält (und weil weniger Zuweisungs-Overhead da ist, kann
@code{mysql_use_result()} schneller sein). Die Nachteile liegen darin, dass
Sie jede Zeile schnell verarbeiten müssen, um zu vermeiden, den Server zu
blockieren. Ausserdem haben Sie keinen wahlfreien (random) Zugriff auf die
Zeilen innerhalb einer Ergebnismenge (Sie können auf die Zeilen nur
sequentiell zugreifen), und Sie wissen nicht, wie viele Zeilen sich in der
Ergebnismenge befinden, bis Sie sie alle abgerufen haben. Darüber hinaus
@emph{müssen} Sie alle Zeilen abrufen, selbst wenn Sie während des Abrufs
feststellen, dass Sie die Information gefunden haben, nach der Sie suchen.

Die API ermöglicht Clients, auf die Anfragen entsprechend zu antworten
(Zeilen nur wenn nötig abzurufen), ohne zu wissen, ob die Anfragen ein
@code{SELECT} ist oder nicht. Das erreichen Sie durch Aufruf von
@code{mysql_store_result()} nach jedem @code{mysql_query()} (oder
@code{mysql_real_query()}). Wenn der Ergebnismengenaufruf erfolgreich ist,
war die Anfrage ein @code{SELECT} und Sie können die Zeilen lesen. Wenn der
Ergebnismengenaufruf fehlschlägt, rufen Sie @code{mysql_field_count()} auf,
um festzustellen, ob ein Ergebnis erwartet wurde oder nicht. Wenn
@code{mysql_field_count()} 0 zurückgibt, gab die Anfrage keine Daten zurück
(was anzeigt, dass sie kein @code{INSERT}, @code{UPDATE}, @code{DELETE}
usw. war), und es wurde nicht erwartet, dass sie Zeilen zurückgibt. Wenn
@code{mysql_field_count()} ungleich 0 ist, sollte die Anfrage Zeilen
zurückgegeben haben, tat das aber nicht. Das zeigt an, dass die Anfrage ein
@code{SELECT} war, das fehlschlug. Sehen Sie in der Beschreibung von
@code{mysql_field_count()} wegen eines Beispiels nach, wie das gemacht
wird.

Sowohl @code{mysql_store_result()} als auch @code{mysql_use_result()}
gestatten Ihnen, Informationen über die Felder zu erlangen, aus denen die
Ergebnismenge besteht (die Anzahl der Felder, ihre Namen, Typen usw.). Sie
können sequentiell auf Feldinformationen innerhalb der Zeile zugreifen,
indem Sie @code{mysql_fetch_field()} wiederholt aufrufen, oder direkt auf
die Feldnummer innerhalb einer Zeile durch Aufruf von
@code{mysql_fetch_field_direct()}. Die aktuelle Feldcursorposition kann
durch den Aufruf von @code{mysql_field_seek()} geändert werden. Wenn Sie
den Feldcursor setzen, betrifft das nachfolgende Aufrufe von
@code{mysql_fetch_field()}. Sie erhalten alle Feldinformationen auf einmal,
wenn Sie @code{mysql_fetch_fields()} aufrufen.

Um Fehler zu erkennen und zu berichten, stellt MySQL den Zugriff auf
Fehlerinformationen durch die @code{mysql_errno()}- und
@code{mysql_error()}-Funktionen zur Verfügung. Diese geben den Fehlercode
oder die Fehlermeldung für die zuletzt aufgerufenen Funktionen zur
Verfügung, die erfolgreich sein oder fehlschlagen können, so dass Sie
feststellen können, wann ein Fehler auftrat und welcher es war.


@node C API functions, C Thread functions, C API function overview, C
@c German node C-API-Funktionen
@subsection C-API-Funktionsbeschreibungen


In den unten stehenden Beschreibungen bedeutet ein Parameter oder
Rückgabewert von @code{NULL} @code{NULL} im Sinne der
C-Programmier-Sprache, nicht einen MySQL-@code{NULL}-Wert.

Funktionen, die einen Wert zurückgeben, geben allgemein einen Zeiger oder
eine Ganzzahl zurück. Falls nicht anders angegeben geben Funktionen, die
einen Zeiger zurückgeben, einen Nicht-@code{NULL}-Wert zurück, um Erfolg
anzuzeigen, oder einen @code{NULL}-Wert, um einen Fehler anzuzeigen.
Funktionen, die eine Ganzzahl zurückgeben, geben 0 zurück, um Erfolg
anzuzeigen, und Nicht-0, um einen Fehler anzuzeigen. Beachten Sie, dass
``Nicht-0'' genau das bedeutet. Wenn die Funktionsbeschreibung nichts
anderes aussagt, testen Sie nicht gegen einen anderen Wert als 0:

@example
if (ergebnis)                   /* korrekt */
    ... FEHLER ...

if (ergebnis < 0)               /* nicht korrekt */
    ... FEHLER ...

if (ergebnis == -1)             /* nicht korrekt */
    ... FEHLER ...
@end example

Wenn eine Funktion einen Fehler zurückgibt, listet der Unterabschnitt
@strong{Errors} der Funktionsbeschreibung die möglichen Fehlertypen auf.
Sie finden heraus, welcher davon auftrat, indem Sie @code{mysql_errno()}
aufrufen. Eine Zeichenketten-Darstellung des Fehler kann durch Aufruf von
@code{mysql_error()} erlangt werden.


@menu
* mysql_affected_rows::         
* mysql_close::                 
* mysql_connect::               
* mysql_change_user::           
* mysql_character_set_name::    
* mysql_create_db::             
* mysql_data_seek::             
* mysql_debug::                 
* mysql_drop_db::               
* mysql_dump_debug_info::       
* mysql_eof::                   
* mysql_errno::                 
* mysql_error::                 
* mysql_escape_string::         
* mysql_fetch_field::           
* mysql_fetch_fields::          
* mysql_fetch_field_direct::    
* mysql_fetch_lengths::         
* mysql_fetch_row::             
* mysql_field_count::           
* mysql_field_seek::            
* mysql_field_tell::            
* mysql_free_result::           
* mysql_get_client_info::       
* mysql_get_host_info::         
* mysql_get_proto_info::        
* mysql_get_server_info::       
* mysql_info::                  
* mysql_init::                  
* mysql_insert_id::             
* mysql_kill::                  
* mysql_list_dbs::              
* mysql_list_fields::           
* mysql_list_processes::        
* mysql_list_tables::           
* mysql_num_fields::            
* mysql_num_rows::              
* mysql_options::               
* mysql_ping::                  
* mysql_query::                 
* mysql_real_connect::          
* mysql_real_escape_string::    
* mysql_real_query::            
* mysql_reload::                
* mysql_row_seek::              
* mysql_row_tell::              
* mysql_select_db::             
* mysql_shutdown::              
* mysql_stat::                  
* mysql_store_result::          
* mysql_thread_id::             
* mysql_use_result::            
@end menu

@node mysql_affected_rows, mysql_close, C API functions, C API functions
@c German node mysql_affected_rows
@subsubsection @code{mysql_affected_rows()}

@findex @code{mysql_affected_rows()}

@code{my_ulonglong mysql_affected_rows(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt die Anzahl von Zeilen zurück, die durch das letzte @code{UPDATE}
geändert, durch das letzte @code{DELETE} gelöscht oder durch das letzte
@code{INSERT} eingefügt wurden. Kann direkt nach @code{mysql_query()}
aufgerufen werden, bei @code{UPDATE}-, @code{DELETE}- oder
@code{INSERT}-Statements. Bei @code{SELECT}-Statements funktioniert
@code{mysql_affected_rows()} wie @code{mysql_num_rows()}.

@subsubheading Rückgabewerte

Eine Ganzzahl größer als 0 gibt die Anzahl von Zeilen an, die betroffen
oder abgerufen wurden. 0 gibt an, dass keine Datensätze bei einem
@code{UPDATE}-Statement geändert wurden, keine Zeilen der
@code{WHERE}-Klausel in der Anfrage entsprachen oder dass bislang keine
Anfrage ausgeführt wurde. -1 gibt an, dass die Anfrage einen Fehler
zurückgab oder dass - bei einer @code{SELECT}-Anfrage -
@code{mysql_affected_rows()} vor @code{mysql_store_result()} aufgerufen
wurde.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

@example
mysql_query(&mysql,"UPDATE produkte SET kosten=kosten*1.25 WHERE gruppe=10");
printf("%ld produkte updated",(long) mysql_affected_rows(&mysql));
@end example

Wenn man den Flag @code{CLIENT_FOUND_ROWS} angibt, wenn man sich mit
@code{mysqld} verbindet, gibt @code{mysql_affected_rows()} die Anzahl von
Zeilen zurück, die mit dem @code{WHERE}-Statement bei
@code{UPDATE}-Statements übereinstimmten.

Beachten Sie bei der Benutzung des @code{REPLACE}-Befehls, dass
@code{mysql_affected_rows()} 2 zurückgibt, wenn die neue Zeile eine alte
Zeile ersetzte. Das liegt daran, dass in diesem Fall eine neue Zeile
eingefügt und dann das alte Duplikat gelöscht wurde.


@node mysql_close, mysql_connect, mysql_affected_rows, C API functions
@c German node mysql_close
@subsubsection @code{mysql_close()}

@findex @code{mysql_close()}

@code{void mysql_close(MYSQL *mysql)}

@subsubheading Beschreibung
Schließt eine vorher geöffnete Verbindung. @code{mysql_close()} gibt auch
den Verbindungs-Handle frei, der von @code{mysql} zugewiesen wurde, wenn
der Handle automatisch mit @code{mysql_init()} oder @code{mysql_connect()}
zugewiesen wurde.

@subsubheading Rückgabewerte

Keine.

@subsubheading Fehler

Keine.


@node mysql_connect, mysql_change_user, mysql_close, C API functions
@c German node mysql_connect
@subsubsection @code{mysql_connect()}

@findex @code{mysql_connect()}

@code{MYSQL *mysql_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd)}

@subsubheading Beschreibung

Diese Funktion ist veraltet. Sie sollten statt dessen
@code{mysql_real_connect()} benutzen.

@code{mysql_connect()} versucht, eine Verbindung zu einer
MySQL-Datenbankmaschine aufzubauen, die auf @code{host} läuft.
@code{mysql_connect()} muss erfolgreich beendet werden, bevor Sie irgend
welche weiteren API-Funktionen aufrufen können, mit Ausnahme von
@code{mysql_get_client_info()}.

Die Bedeutung der Parameter ist dieselbe wie die entsprechenden Parameter
bei @code{mysql_real_connect()}, mit dem Unterschied, dass die
Verbindungsparameter @code{NULL} sein dürfen. In diesem Fall weist die
C-API automatisch Speicher für die Verbindungsstruktur zu und gibt diesen
frei, wenn Sie @code{mysql_close()} aufrufen. Der Nachteil dieses Ansatzes
besteht darin, dass Sie keine Fehlermeldung abrufen können, wenn die
Verbindung fehlschlägt. (Um Fehlerinformationen von @code{mysql_errno()}
oder @code{mysql_error()} abrufen zu können, müssen Sie einen gültigen
@code{MYSQL}-Zeiger angeben.)

@subsubheading Rückgabewerte

Dieselben wie für @code{mysql_real_connect()}.

@subsubheading Fehler

Dieselben wie für @code{mysql_real_connect()}.


@node mysql_change_user, mysql_character_set_name, mysql_connect, C API functions
@c German node mysql_change_user
@subsubsection @code{mysql_change_user()}

@findex @code{mysql_change_user()}

@code{my_bool mysql_change_user(MYSQL *mysql, const char *user, const
char *password, const char *db)}

@subsubheading Beschreibung

Ändert den Benutzer und veranlasst, dass die Datenbank, die mit @code{db}
angegeben wurde, die vorgabemäßige (aktuelle) Datenbank für die Verbindung
wird, die durch @code{mysql} festgelegt wurde. In nachfolgenden Anfragen
ist diese Datenbank die Vorgabe für Tabellenverweise, bei denen nicht
explizit eine Datenbank angegeben wird.

Diese Funktion wurde in MySQL-Version 3.23.3 eingeführt.

@code{mysql_change_user()} schlägt fehl, wenn sich der Benutzer nicht
authentifizieren kann oder wenn er keine Zugriffsrechte auf die Datenbank
hat. In diesem Fall werden Benutzer und Datenbank nicht geändert.

Der @code{db}-Parameter kann auf @code{NULL} gesetzt werden, wenn Sie keine
vorgabemäßige Datenbank haben wollen.

@subsubheading Rückgabewerte

0 für Erfolg. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

Dieselben, die Sie von @code{mysql_real_connect()} erhalten.

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurde in nicht korrekter Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler ist aufgetreten.
@item ER_UNKNOWN_COM_ERROR
Der MySQL-Server hat diesen Befehl nicht implementiert (wahrscheinlich ein
alter Server).
@item ER_ACCESS_DENIED_ERROR
Benutzername oder Passwort sind falsch.
@item ER_BAD_DB_ERROR
Die Datenbank existiert nicht.
@item ER_DBACCESS_DENIED_ERROR
Der Benutzer hat keine Zugriffsrechte auf die Datenbank.
@item ER_WRONG_DB_NAME
Der Datenbankname war zu lang.
@end table

@subsubheading Beispiel

@example
if (mysql_change_user(&mysql, "benutzer", "passwort", "neue_datenbank"))
@{
   fprintf(stderr, "Änderung des Benutzers fehlgeschlagen. Fehler: %s\n",
           mysql_error(&mysql));
@}
@end example


@node mysql_character_set_name, mysql_create_db, mysql_change_user, C API functions
@c German node mysql_character_set_name
@subsubsection @code{mysql_character_set_name()}

@findex @code{mysql_character_set_name()}

@code{const char *mysql_character_set_name(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt den vorgabemäßigen Zeichensatz für die aktuelle Verbindung zurück.

@subsubheading Rückgabewerte

Der vorgabemäßige Zeichensatz

@subsubheading Fehler

Keine.


@node mysql_create_db, mysql_data_seek, mysql_character_set_name, C API functions
@c German node mysql_create_db
@subsubsection @code{mysql_create_db()}

@findex @code{mysql_create_db()}

@code{int mysql_create_db(MYSQL *mysql, const char *db)}

@subsubheading Beschreibung
Erzeugt die Datenbank, die durch den @code{db}-Parameter angegeben wird.

Diese Funktion ist veraltet. Vorzugsweise sollten Sie @code{mysql_query()}
benutzen, um statt dessen ein SQL-@code{CREATE DATABASE}-Statement
abzusetzen.

@subsubheading Rückgabewerte

0, wenn die Datenbank erfolgreich erzeugt wurde. Nicht-0, wenn ein Fehler
auftrat.

@subsubheading Fehler
@table @code

@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden in nicht korrekter Reihenfolge ausgeführt.

@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.

@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.

@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table

@subsubheading Beispiel

@example
if(mysql_create_db(&mysql, "meine_datenbank"))
@{
   fprintf(stderr, "Erzeugung der neuen Datenbank fehlgeschlagen. Fehler: %s\n",
           mysql_error(&mysql));
@}
@end example


@node mysql_data_seek, mysql_debug, mysql_create_db, C API functions
@c German node mysql_data_seek
@subsubsection @code{mysql_data_seek()}

@findex @code{mysql_data_seek()}

@code{void mysql_data_seek(MYSQL_RES *result, unsigned long long offset)}

@subsubheading Beschreibung
Sucht bis zu einer beliebigen Zeile in einer Anfrageergebnismenge. Das
setzt voraus, dass die Ergebnismengenstruktur das gesamte Anfrageergebnis
enthält. Daher kann @code{mysql_data_seek()} nur in Verbindung mit
@code{mysql_store_result()} benutzt werden, nicht in Verbindung mit
@code{mysql_use_result()}.

Der Offset sollte ein Wert im Bereich von 0 bis
@code{mysql_num_rows(ergebnis)-1} sein.

@subsubheading Rückgabewerte

Keine.

@subsubheading Fehler

Keine.


@node mysql_debug, mysql_drop_db, mysql_data_seek, C API functions
@c German node mysql_debug
@subsubsection @code{mysql_debug()}

@findex @code{mysql_debug()}

@code{void mysql_debug(char *debug)}

@subsubheading Beschreibung
Führt ein @code{DBUG_PUSH} mit der angegebenen Zeichenkette durch.
@code{mysql_debug()} benutzt die Debug-Bibliothek von Fred Fish. Um diese
Funktion benutzen zu können, müssen Sie die Client-Bibliothek so
kompilieren, dass sie Debuggen unterstützt. @xref{Debugging server}.
@xref{Debugging client}.

@subsubheading Rückgabewerte

Keine.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

Der unten stehende Aufruf führt dazu, dass die Client-Bibliothek eine
Trace-Datei in @file{/tmp/client.trace} auf der Client-Maschine erzeugt:

@example
mysql_debug("d:t:O,/tmp/client.trace");
@end example


@node mysql_drop_db, mysql_dump_debug_info, mysql_debug, C API functions
@c German node mysql_drop_db
@subsubsection @code{mysql_drop_db()}

@findex @code{mysql_drop_db()}

@code{int mysql_drop_db(MYSQL *mysql, const char *db)}

@subsubheading Beschreibung
Löscht die Datenbank, die durch den @code{db}-Parameter angegeben wird.

Diese Funktion ist veraltet. Benutzen Sie vorzugsweise
@code{mysql_query()}, um statt dessen ein SQL-@code{DROP
DATABASE}-Statement abzusetzen.

@subsubheading Rückgabewerte

0, wenn die Datenbank erfolgreich gelöscht wurde. Nicht-0, wenn ein Fehler
auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table

@subsubheading Beispiel

@example
if(mysql_drop_db(&mysql, "meine_datenbank"))
  fprintf(stderr, "Löschen der Datenbank fehlgeschlagen: Fehler: %s\n",
          mysql_error(&mysql));
@end example


@node mysql_dump_debug_info, mysql_eof, mysql_drop_db, C API functions
@c German node mysql_dump_debug_info
@subsubsection @code{mysql_dump_debug_info()}

@findex @code{mysql_dump_debug_info()}

@code{int mysql_dump_debug_info(MYSQL *mysql)}

@subsubheading Beschreibung

Weist den Server an, Debug-Informationen ins Log zu schreiben. Damit das
funktioniert, muss der verbundene Benutzer die
@strong{process}-Berechtigung haben.

@subsubheading Rückgabewerte

0, wenn der Befehl erfolgreich war. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler
@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_eof, mysql_errno, mysql_dump_debug_info, C API functions
@c German node mysql_eof
@subsubsection @code{mysql_eof()}

@findex @code{mysql_eof()}

@code{my_bool mysql_eof(MYSQL_RES *result)}

@subsubheading Beschreibung

Diese Funktion ist veraltet. Benutzen Sie statt dessen @code{mysql_errno()}
oder @code{mysql_error()}.

@code{mysql_eof()} stellt fest, ob die letzte Zeile einer Ergebnismenge
gelesen wurde oder nicht.

Wenn Sie eine Ergebnismenge durch einen erfolgreichen Aufruf von
@code{mysql_store_result()} erhalten, erhält der Client den gesamten Satz
in einer Operation. In diesem Fall bedeutet eine @code{NULL}-Rückgabe von
@code{mysql_fetch_row()} immer, dass das Ende der Ergebnismenge erreicht
wurde und es unnötig ist, @code{mysql_eof()} aufzurufen.

Wenn Sie auf der anderen Seite @code{mysql_use_result()} aufrufen, um den
Abruf einer Ergebnismenge zu initialisieren, werden die Zeilen des Satzes
Zeile für Zeile vom Server erlangt, indem Sie @code{mysql_fetch_row()}
wiederholt aufrufen. Weil während dieses Prozesses ein Verbindungsfehler
auftreten kann, bedeutet ein @code{NULL}-Rückgabewert von
@code{mysql_fetch_row()} nicht notwendigerweise, dass das Ende der
Ergebnismenge auf normale Weise erreicht wurde. In diesem Fall können Sie
@code{mysql_eof()} benutzen, um festzustellen, was passiert ist.
@code{mysql_eof()} gibt einen Nicht-0-Wert zurück, wenn das Ende der
Ergebnismenge erreicht wurde, und 0, wenn ein Fehler auftrat.

Historisch liegt @code{mysql_eof()} vor den Standard-MySQL-Fehlerfunktionen
@code{mysql_errno()} und @code{mysql_error()}. Weil diese Fehlerfunktionen
dieselben Informationen zur Verfügung stellen, wird ihre Benutzung des des
veralteten @code{mysql_eof()} empfohlen. (Sie stellen in der Tat sogar mehr
Informationen zur Verfügung, weil @code{mysql_eof()} nur einen Bool'schen
Wert zurückgibt, während die Fehlerfunktionen den Grund angeben, warum der
Fehler auftrat.)

@subsubheading Rückgabewerte

0, wenn kein Fehler auftrat. Nicht-0, wenn das Ende der Ergebnismenge
erreicht wurde.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

Folgendes Beispiel zeigt, wie Sie @code{mysql_eof()} benutzen können:

@example
mysql_query(&mysql,"SELECT * FROM tabelle");
ergebnis = mysql_use_result(&mysql);
while((zeile = mysql_fetch_row(ergebnis)))
@{
    // Daten verarbeiten usw.
@}
if(!mysql_eof(ergebnis))  // mysql_fetch_row() schlug wegen eines Fehlers fehl
@{
    fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
@}
@end example

Sie können denselben Effekt jedoch auch mit den
Standard-MySQL-Fehlerfunktionen erreichen:

@example
mysql_query(&mysql,"SELECT * FROM tabelle");
result = mysql_use_result(&mysql);
while((zeile = mysql_fetch_row(ergebnis)))
@{
    // Daten verarbeiten usw.
@}
if(mysql_errno(&mysql))  // mysql_fetch_row() schlug wegen eines Fehlers fehl
@{
    fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
@}
@end example


@node mysql_errno, mysql_error, mysql_eof, C API functions
@c German node mysql_errno
@subsubsection @code{mysql_errno()}

@findex @code{mysql_errno()}

@code{unsigned int mysql_errno(MYSQL *mysql)}

@subsubheading Beschreibung

Für die von @code{mysql} angegebene Verbindung gibt @code{mysql_errno()}
den Fehlercode für die zuletzt aufgerufene API-Funktion zurück, die
erfolgreich sein oder fehlschlagen kann. Ein Rückgabewert von 0 bedeutet,
dass kein Fehler auftrat. Client-Fehlermeldungsnummern sind in der
MySQL-@file{errmsg.h}-Header-Datei aufgelistet.
Server-Fehlermeldungsnummern sind in @file{mysqld_error.h} aufgelistet. In
der MySQL-Quelldistribution finden Sie eine komplette Liste der
Fehlermeldungen und Fehlernummern in der Datei
@file{Docs/mysqld_error.txt}.

@subsubheading Rückgabewerte

Ein Fehlercode-Wert. 0, wenn kein Fehler auftrat.

@subsubheading Fehler

Keine.


@node mysql_error, mysql_escape_string, mysql_errno, C API functions
@c German node mysql_error
@subsubsection @code{mysql_error()}

@findex @code{mysql_error()}

@code{char *mysql_error(MYSQL *mysql)}

@subsubheading Beschreibung

Für die von @code{mysql} angegebene Verbindung gibt @code{mysql_error()}
die Fehlermeldung für die zuletzt aufgerufene API-Funktion zurück, die
erfolgreich sein oder fehlschlagen kann. Eine leere Zeichenkette
(@code{""}) wird zurückgegeben, wenn kein Fehler auftrat. Das bedeutet,
dass folgende zwei Tests äquivalent sind:

@example
if(mysql_errno(&mysql))
@{
    // Ein Fehler trat auf
@}

if(mysql_error(&mysql)[0] != '\0')
@{
    // Ein Fehler trat auf
@}
@end example

Die Sprache der Client-Fehlermeldungen kann durch erneutes Kompilieren der
MySQL-Client-Bibliothek geändert werden. Sie können Fehlermeldungen in
mehreren unterschiedlichen Sprachen auswählen. @xref{Languages}.

@subsubheading Rückgabewerte

Eine Zeichenkette, die den Fehler beschreibt. Eine leere Zeichenkette, wenn
kein Fehler auftrat.

@subsubheading Fehler

Keine.


@node mysql_escape_string, mysql_fetch_field, mysql_error, C API functions
@c German node mysql_escape_string
@subsubsection @code{mysql_escape_string()}

@findex @code{mysql_escape_string()}

Statt dessen sollten Sie @code{mysql_real_escape_string()} benutzen!

Das ist identisch mit @code{mysql_real_escape_string()}, ausser dass die
Verbindung als erstes Argument genommen wird.
@code{mysql_real_escape_string()} escapet die Zeichenkette gemäß dem
aktuellen Zeichensatz, wohingegen @code{mysql_escape_string()} die aktuelle
Zeichensatzeinstellung ignoriert.


@node mysql_fetch_field, mysql_fetch_fields, mysql_escape_string, C API functions
@c German node mysql_fetch_field
@subsubsection @code{mysql_fetch_field()}

@findex @code{mysql_fetch_field()}

@code{MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)}

@subsubheading Beschreibung

Gibt die Definition einer Spalte der Ergebnismenge als
@code{MYSQL_FIELD}-Struktur zurück. Rufen Sie diese Funktion wiederholt
auf, um Informationen über alle Spalten in der Ergebnismenge zu erhalten.
@code{mysql_fetch_field()} gibt @code{NULL} zurück, wenn es keine weiteren
Felder mehr gibt.

@code{mysql_fetch_field()} wird zurückgesetzt, so dass sie Informationen
über das erste Feld zurückgibt, und zwar jedes Mal, wenn Sie eine neue
@code{SELECT}-Anfrage ausführen. Das von @code{mysql_fetch_field()}
zurückgegebene Feld wird auch durch Aufrufe von @code{mysql_field_seek()}
betroffen.

Wenn Sie @code{mysql_query()} aufgerufen haben, um ein @code{SELECT} auf
eine Tabelle auszuführen, aber nicht @code{mysql_store_result()} aufgerufen
haben, gibt MySQL die vorgabemäßige BLOB-Länge (8 KB) zurück, wenn Sie
@code{mysql_fetch_field()} aufrufen, um nach der Länge eines
@code{BLOB}-Felds zu fragen. (Die Größe von 8 KB wird gewählt, weil MySQL
die maximale Länge des @code{BLOB} nicht kennt. Das wird irgendwann einmal
konfigurierbar gemacht.) Nachdem Sie die Ergebnismenge erst einmal
abgerufen haben, enthält @code{field->max_length} die Länge des längsten
Werts dieser Spalte in der bestimmten Anfrage.

@subsubheading Rückgabewerte

Die @code{MYSQL_FIELD}-Struktur der aktuellen Spalte. @code{NULL}, wenn
keine Spalten mehr übrig sind.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

@example
MYSQL_FIELD *field;

while((field = mysql_fetch_field(ergebnis)))
@{
    printf("Feldname %s\n", field->name);
@}
@end example


@node mysql_fetch_fields, mysql_fetch_field_direct, mysql_fetch_field, C API functions
@c German node mysql_fetch_fields
@subsubsection @code{mysql_fetch_fields()}

@findex @code{mysql_fetch_fields()}

@code{MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)}

@subsubheading Beschreibung

Gibt ein Array aller @code{MYSQL_FIELD}-Strukturen für eine Ergebnismenge
zurück. Jede Struktur stellt Felddefinitionen für eine Spalte der
Ergebnismenge zur Verfügung.

@subsubheading Rückgabewerte

Ein Array von @code{MYSQL_FIELD}-Strukturen für alle Spalten einer
Ergebnismenge.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

@example
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *fields;

num_fields = mysql_num_fields(ergebnis);
fields = mysql_fetch_fields(ergebnis);
for(i = 0; i < num_fields; i++)
@{
   printf("Feld %u ist %s\n", i, fields[i].name);
@}
@end example


@node mysql_fetch_field_direct, mysql_fetch_lengths, mysql_fetch_fields, C API functions
@c German node mysql_fetch_field_direct
@subsubsection @code{mysql_fetch_field_direct()}

@findex @code{mysql_fetch_field_direct()}

@code{MYSQL_FIELD *mysql_fetch_field_direct(MYSQL_RES *result, unsigned int feldnr)}

@subsubheading Beschreibung

Mit der Angabe einer Feldnummer @code{feldnr} für eine Spalte innerhalb
einer Ergebnismenge gibt sie die Felddefinition dieser Spalte als
@code{MYSQL_FIELD}-Struktur zurück. Sie können diese Funktion verwenden, um
die Definition für eine beliebige Spalte abzurufen. Der Wert von
@code{feldnr} sollte im Bereich von 0 bis
@code{mysql_num_fields(ergebnis)-1} liegen.

@subsubheading Rückgabewerte

Die @code{MYSQL_FIELD}-Struktur für die angegebene Spalte.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

@example
unsigned int num_fields;
unsigned int i;
MYSQL_FIELD *field;

num_fields = mysql_num_fields(ergebnis);
for(i = 0; i < num_fields; i++)
@{
    field = mysql_fetch_field_direct(ergebnis, i);
    printf("Feld %u ist %s\n", i, field->name);
@}
@end example


@node mysql_fetch_lengths, mysql_fetch_row, mysql_fetch_field_direct, C API functions
@c German node mysql_fetch_lengths
@subsubsection @code{mysql_fetch_lengths()}

@findex @code{mysql_fetch_lengths()}

@code{unsigned long *mysql_fetch_lengths(MYSQL_RES *result)}

@subsubheading Beschreibung

Gibt die Länge der Spalten der aktuellen Zeile innerhalb der Ergebnismenge
zurück. Wenn Sie vorhaben, Feldwerte zu kopieren, sind diese
Längeninformationen auch nützlich für Optimierungen, weil Sie vermeiden
können, @code{strlen()} aufzurufen. Wenn die Ergebnismenge Binärdaten
enthält, kommt hinzu, dass Sie diese Funktion benutzen @emph{müssen}, um
die Größe der Daten zu bestimmen, weil @code{strlen()} falsche Ergebnisse
für Felder zurückgibt, die NULL-Zeichen enthalten.

Die Länge leerer Spalten und von Spalten, die @code{NULL}-Werte enthalten,
ist 0. Um zu sehen, wie man diese beiden Fälle auseinander hält, sehen Sie
in der Beschreibung von @code{mysql_fetch_row()} nach.

@subsubheading Rückgabewerte

Ein Array vorzeichenloser langer Ganzzahlen (long integer), die die Größe
jeder Spalte darstellen (ohne irgend welche begrenzenden NULL-Zeichen).
@code{NULL}, wenn ein Fehler auftrat.

@subsubheading Fehler

@code{mysql_fetch_lengths()} ist nur für die aktuelle Zeile der
Ergebnismenge gültig. Sie gibt @code{NULL} zurück, wenn Sie sie vor
@code{mysql_fetch_row()} oder nach dem Abruf aller Zeilen im Ergebnis
aufrufen.

@subsubheading Beispiel

@example
MYSQL_ROW zeile;
unsigned long *laengen;
unsigned int anzahl_felder;
unsigned int i;

zeile = mysql_fetch_row(ergebnis);
if (zeile)
@{
    anzahl_felder = mysql_num_fields(ergebnis);
    laengen = mysql_fetch_lengths(ergebnis);
    for(i = 0; i < anzahl_felder; i++)
    @{
         printf("Spalte %u ist %lu Bytes lang.\n", i, lengths[i]);
    @}
@}
@end example


@node mysql_fetch_row, mysql_field_count, mysql_fetch_lengths, C API functions
@c German node mysql_fetch_row
@subsubsection @code{mysql_fetch_row()}

@findex @code{mysql_fetch_row()}

@code{MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)}

@subsubheading Beschreibung

Ruft die nächste Zeile einer Ergebnismenge ab. Wenn sie nach
@code{mysql_store_result()} benutzt wird, gibt @code{mysql_fetch_row()}
@code{NULL} zurück, wenn es keine weiteren Zeilen zum Abruf mehr gibt. Wenn
sie nach @code{mysql_use_result()} benutzt wird, gibt
@code{mysql_fetch_row()} @code{NULL} zurück, wenn es keine Zeilen mehr zum
Abruf gibt oder wenn ein Fehler auftrat.

Die Anzahl von Werten in der Zeile wird durch
@code{mysql_num_fields(ergebnis)} gegeben. Wenn @code{zeile} den
Rückgabewert eines Aufrufs von @code{mysql_fetch_row()} enthält, wird auf
Zeiger auf die Werte als @code{zeile[0]} bis
@code{zeile[mysql_num_fields(ergebnis)-1]} zugegriffen. @code{NULL}-Werte
in der Zeile werden durch @code{NULL}-Zeiger angezeigt.

Die Längen der Feldwerte in der Zeile können durch Aufruf von
@code{mysql_fetch_lengths()} bestimmt werden. Leere Felder und Felder, die
@code{NULL} enthalten, haben beide die Länge 0. Sie können diese
auseinanderhalten, indem Sie den Zeiger für den Feldwert überprüfen. Wenn
der Zeiger @code{NULL} ist, ist das Feld @code{NULL}, ansonsten ist das
Feld leer.

@subsubheading Rückgabewerte

Eine @code{MYSQL_ROW}-Struktur für die nächste Zeile. @code{NULL}, wenn
keine weiteren Zeilen abzurufen sind oder wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table

@subsubheading Beispiel

@example
MYSQL_ROW zeile;
unsigned int anzahl_felder;
unsigned int i;

anzahl_felder = mysql_num_fields(ergebnis);
while ((zeile = mysql_fetch_row(ergebnis)))
@{
   unsigned long *laengen;
   laengen = mysql_fetch_lengths(ergebnis);
   for(i = 0; i < anzahl_felder; i++)
   @{
       printf("[%.*s] ", (int) laengen[i], zeile[i] ? zeile[i] : "NULL");
   @}
   printf("\n");
@}
@end example


@node mysql_field_count, mysql_field_seek, mysql_fetch_row, C API functions
@c German node mysql_field_count
@subsubsection @code{mysql_field_count()}

@findex @code{mysql_field_count()}

@code{unsigned int mysql_field_count(MYSQL *mysql)}

Wenn Sie eine Version von MySQL vor Version 3.22.24 benutzen, sollten Sie
statt dessen @code{unsigned int mysql_num_fields(MYSQL *mysql)} benutzen.

@subsubheading Beschreibung

Gibt die Anzahl von Spalten der letzten Anfrage auf der Verbindung zurück.

Normalerweise wird diese Funktion benutzt, wenn @code{mysql_store_result()}
@code{NULL} zurückgab (und Sie daher keinen Ergebnismengen-Zeiger haben).
In diesem Fall können Sie @code{mysql_field_count()} aufrufen, um
festzustellen, ob @code{mysql_store_result()} ein leeres Ergebnis hätte
zurückgeben sollen oder nicht. Das gestattet dem Client-Programm, die
richtigen Aktionen zu ergreifen, ohne wissen zu müssen, ob die Anfrage ein
@code{SELECT} war oder nicht (oder ein @code{SELECT}-ähnliches Statement).
Das unten stehende Beispiel zeigt, wie man das machen kann.

@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.

@subsubheading Rückgabewerte

Eine vorzeichenlose Ganzzahl, die die Anzahl von Feldern in einer
Ergebnismenge darstellt.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

@example
MYSQL_RES *result;
unsigned int anzahl_felder;
unsigned int anzahl_zeilen;

if (mysql_query(&mysql,anfrage))
@{
    // FEHLER
@}
else // Anfrage war erfolgreich, zurückgegebene Daten verarbeiten
@{
    ergebnis = mysql_store_result(&mysql);
    if (ergebnis)  // Es gibt Zeilen
    @{
        anzahl_felder = mysql_num_fields(ergebnis);
        // Zeilen abrufen, dann mysql_free_result(result) aufrufen
    @}
    else  // mysql_store_result() gab nichts zurück, hätte es etwas zurückgeben sollen?
    @{
        if(mysql_field_count(&mysql) == 0)
        @{
            // Anfrage gibt keine Daten zurück
            // (Anfrage war kein SELECT)
            anzahl_zeilen = mysql_affected_rows(&mysql);
        @}
        else // mysql_store_result() hätte Daten zurückgeben sollen
        @{
            fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
        @}
    @}
@}
@end example

Eine Alternative besteht darin, den @code{mysql_field_count(&mysql)}-Aufruf
durch @code{mysql_errno(&mysql)} zu ersetzen. In diesem Fall überprüfen Sie
direkt auf einen Fehler von @code{mysql_store_result()}, statt aus dem Wert
von @code{mysql_field_count()} zu schlussfolgern, ob das Statement ein
@code{SELECT} war oder nicht.


@node mysql_field_seek, mysql_field_tell, mysql_field_count, C API functions
@c German node mysql_field_seek
@subsubsection @code{mysql_field_seek()}

@findex @code{mysql_field_seek()}

@code{MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES *result, MYSQL_FIELD_OFFSET offset)}

@subsubheading Beschreibung

Setzt den Feldcursor auf den angegebenen Offset. Der nächste Aufruf von
@code{mysql_fetch_field()} ruf die Felddefinition der Spalte ab, die mit
diesem Offset verknüpft ist.

Um bis zum Anfang einer Zeile zu suchen, geben Sie einen @code{offset}-Wert
von 0 an.

@subsubheading Rückgabewerte

Der vorherige Wert des Feldcursors.

@subsubheading Fehler

Keine.


@node mysql_field_tell, mysql_free_result, mysql_field_seek, C API functions
@c German node mysql_field_tell
@subsubsection @code{mysql_field_tell()}

@findex @code{mysql_field_tell()}

@code{MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES *result)}

@subsubheading Beschreibung

Gibt die Position des Feldcursors für die letzte @code{mysql_fetch_field()}
zurück. Dieser Wert kann als Argument für @code{mysql_field_seek()} benutzt
werden.

@subsubheading Rückgabewerte

Der aktuelle Offset des Feldcursors.

@subsubheading Fehler

Keine.


@node mysql_free_result, mysql_get_client_info, mysql_field_tell, C API functions
@c German node mysql_free_result
@subsubsection @code{mysql_free_result()}

@findex @code{mysql_free_result()}

@code{void mysql_free_result(MYSQL_RES *result)}

@subsubheading Beschreibung

Gibt den Speicher frei, der für eine Ergebnismenge von
@code{mysql_store_result()}, @code{mysql_use_result()},
@code{mysql_list_dbs()} usw. zugewiesen wurde. Wenn Sie mit einer
Ergebnismenge fertig sind, müssen Sie den von ihr benutzten Speicher durch
Aufruf von @code{mysql_free_result()} freigeben.

@subsubheading Rückgabewerte

Keine.

@subsubheading Fehler

Keine.


@node mysql_get_client_info, mysql_get_host_info, mysql_free_result, C API functions
@c German node mysql_get_client_info
@subsubsection @code{mysql_get_client_info()}

@findex @code{mysql_get_client_info()}

@code{char *mysql_get_client_info(void)}

@subsubheading Beschreibung

Returns a string that represents the client Bibliothek version.

@subsubheading Rückgabewerte

A character string that represents the MySQL-Client Bibliothek version.

@subsubheading Fehler
Keine.


@node mysql_get_host_info, mysql_get_proto_info, mysql_get_client_info, C API functions
@c German node mysql_get_host_info
@subsubsection @code{mysql_get_host_info()}

@findex @code{mysql_get_host_info()}

@code{char *mysql_get_host_info(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt eine Zeichenkette zurück, die den Typ der benutzten Verbindung
beschreibt, inklusive des Server-Hostnamens.

@subsubheading Rückgabewerte

Eine Zeichenkette, die den Server-Hostnamen und den Verbindungstyp
bezeichnet.

@subsubheading Fehler

Keine.


@node mysql_get_proto_info, mysql_get_server_info, mysql_get_host_info, C API functions
@c German node mysql_get_proto_info
@subsubsection @code{mysql_get_proto_info()}

@findex @code{mysql_get_proto_info()}

@code{unsigned int mysql_get_proto_info(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt die Protokollversion zurück, die von der aktuellen Verbindung benutzt
wird.

@subsubheading Rückgabewerte

Eine vorzeichenlose Ganzzahl, die die Protokollversion bezeichnet, die von
der aktuellen Verbindung benutzt wird.

@subsubheading Fehler

Keine.


@node mysql_get_server_info, mysql_info, mysql_get_proto_info, C API functions
@c German node mysql_get_server_info
@subsubsection @code{mysql_get_server_info()}

@findex @code{mysql_get_server_info()}

@code{char *mysql_get_server_info(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt eine Zeichenkette zurück, die die Server-Versionsnummer bezeichnet.

@subsubheading Rückgabewerte

Eine Zeichenkette, die die Server-Versionsnummer bezeichnet.

@subsubheading Fehler

Keine.


@node mysql_info, mysql_init, mysql_get_server_info, C API functions
@c German node mysql_info
@subsubsection @code{mysql_info()}

@findex @code{mysql_info()}

@code{char *mysql_info(MYSQL *mysql)}

@subsubheading Beschreibung

Ruft eine Zeichenkette ab, die Informationen über die zuletzt ausgeführte
Anfrage zurückgibt, aber nur für die unten aufgeführten Statements. Bei
anderen Statements gibt @code{mysql_info()} @code{NULL} zurück. Das Format
der Zeichenkette variiert in Abhängigkeit vom Anfragetyp, wie unten
beschrieben. Die Nummern dienen nur der Veranschaulichung; die Zeichenkette
enthält die der Anfrage entsprechenden Werte.

@table @code
@item INSERT INTO ... SELECT ...
Zeichenkettenformat: @code{Records: 100 Duplicates: 0 Warnings: 0}
@item INSERT INTO ... VALUES (...),(...),(...)...
Zeichenkettenformat: @code{Records: 3  Duplicates: 0  Warnings: 0}
@item LOAD DATA INFILE ...
Zeichenkettenformat: @code{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0}
@item ALTER TABLE
Zeichenkettenformat: @code{Records: 3 Duplicates: 0 Warnings: 0}
@item UPDATE
Zeichenkettenformat: @code{Rows matched: 40 Changed: 40 Warnings: 0}
@end table

Beachten Sie, dass @code{mysql_info()} einen Nicht-@code{NULL}-Wert für das
@code{INSERT ... VALUES}-Statement nur dann zurückgibt, wenn im Statement
mehrfache Wertlisten angegeben sind.

@subsubheading Rückgabewerte

Eine Zeichenkette, die zusätzliche Informationen über die zuletzt
ausgeführte Anfrage bereitstellt. @code{NULL}, wenn für die Anfrage keine
Information verfügbar ist.

@subsubheading Fehler
Keine.


@node mysql_init, mysql_insert_id, mysql_info, C API functions
@c German node mysql_init
@subsubsection @code{mysql_init()}

@findex @code{mysql_init()}

@code{MYSQL *mysql_init(MYSQL *mysql)}

@subsubheading Beschreibung

Alloziert oder initialisiert ein @code{MYSQL}-Objekt, das für
@code{mysql_real_connect()} geeignet ist. Wenn @code{mysql} ein
@code{NULL}-Zeiger ist, alloziert, initialisiert und gibt diese Funktion
ein neues Objekt zurück. Ansonsten wird das Objekt initialisiert und die
Adresse des Objekts zurückgegeben. Wenn @code{mysql_init()} ein neues
Objekt alloziert, wird es freigegeben, wenn @code{mysql_close()} aufgerufen
wird, um die Verbindung zu schließen.

@subsubheading Rückgabewerte

Ein initialisiertes @code{MYSQL*}-Handle. @code{NULL}, wenn der Speicher
nicht ausreichte, um ein neues Objekt zu allozieren.

@subsubheading Fehler

Im Falle von ungenügendem Speicher wird @code{NULL} zurückgegeben.


@node mysql_insert_id, mysql_kill, mysql_init, C API functions
@c German node mysql_insert_id
@subsubsection @code{mysql_insert_id()}

@findex @code{mysql_insert_id()}

@code{my_ulonglong mysql_insert_id(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt die Kennung zurück, die für eine @code{AUTO_INCREMENT}-Spalte durch
die vorherige Anfrage erzeugt wurde. Benutzen Sie diese Funktion, nachdem
Sie eine @code{INSERT}-Anfrage für eine Tabelle durchgeführt haben, die ein
@code{AUTO_INCREMENT}-Feld enthält.

Beachten Sie, dass @code{mysql_insert_id()} @code{0} zurückgibt, wenn die
vorherige Anfrage keinen @code{AUTO_INCREMENT}-Wert erzeugt hat. Wenn Sie
den Wert für spätere Benutzung speichern wollen, stellen Sie sicher, dass
Sie @code{mysql_insert_id()} unmittelbar nach der Anfrage aufrufen, die den
Wert erzeugt.

@code{mysql_insert_id()} wird nach @code{INSERT}- und
@code{UPDATE}-Statements aktualisiert, die einen @code{AUTO_INCREMENT}-Wert
erzeugen oder einen Spaltenwert auf @code{LAST_INSERT_ID(ausdruck)} setzen.
@xref{Miscellaneous functions}.

Beachten Sie auch, dass der Wert der SQL-@code{LAST_INSERT_ID()}-Funktion
immer den aktuellsten erzeugten @code{AUTO_INCREMENT}-Wert enthält, und
zwischen Anfragen nicht zurückgesetzt wird, weil der Wert dieser Funktion
im Server gewartet wird.

@subsubheading Rückgabewerte

Der Wert des @code{AUTO_INCREMENT}-Felds, das durch die vorherige Anfrage
aktualisiert wurde. Gibt 0 zurück, wenn es keine vorherige Anfrage auf der
Verbindung gab oder wenn die Anfrage keinen @code{AUTO_INCREMENT}-Wert
aktualisierte.

@subsubheading Fehler

Keine.


@node mysql_kill, mysql_list_dbs, mysql_insert_id, C API functions
@c German node mysql_kill
@subsubsection @code{mysql_kill()}

@findex @code{mysql_kill()}

@code{int mysql_kill(MYSQL *mysql, unsigned long pid)}

@subsubheading Beschreibung

Bittet den Server, den Thread zu töten, der durch @code{pid} angegeben
wurde.

@subsubheading Rückgabewerte

0 für Erfolg. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_list_dbs, mysql_list_fields, mysql_kill, C API functions
@c German node mysql_list_dbs
@subsubsection @code{mysql_list_dbs()}

@findex @code{mysql_list_dbs()}

@code{MYSQL_RES *mysql_list_dbs(MYSQL *mysql, const char *wild)}

@subsubheading Beschreibung

Gibt eine Ergebnismenge zurück, die aus den Datenbanknamen auf dem Server
besteht, die mit dem einfachen regulären Ausdruck übereinstimmen, der durch
den @code{wild}-Parameter angegeben wird. @code{wild} darf die
Platzhalterzeichen @samp{%} oder @samp{_} enthalten oder ein
@code{NULL}-Zeiger sein, der mit allen Datenbanken übereinstimmt. Der
Aufruf von @code{mysql_list_dbs()} ist ähnlich der Ausführung der Anfrage
@code{SHOW DATABASES [LIKE wild]}.

Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.

@subsubheading Rückgabewerte

Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein
Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_OUT_OF_MEMORY
Kein Speicher mehr.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_list_fields, mysql_list_processes, mysql_list_dbs, C API functions
@c German node mysql_list_fields
@subsubsection  @code{mysql_list_fields()}

@findex @code{mysql_list_fields()}

@code{MYSQL_RES *mysql_list_fields(MYSQL *mysql, const char *table, const char *wild)}

@subsubheading Beschreibung

Gibt eine Ergebnismenge zurück, die aus Feldnamen in der angegebenen
Tabelle bestehen, die mit einem einfachen regulären Ausdruck
übereinstimmen, der durch den @code{wild}-Parameter angegeben wird.
@code{wild} darf die Platzhalterzeichen @samp{%} oder @samp{_} enthalten
oder ein @code{NULL}-Zeiger sein, der mit allen Datenbanken übereinstimmt.
Der Aufruf von @code{mysql_list_fields()} ist ähnlich der Ausführung der
Anfrage @code{SHOW COLUMNS FROM tabelle [LIKE wild]}.

Beachten Sie, dass empfohlen wird, @code{SHOW COLUMNS FROM tabelle} statt
@code{mysql_list_fields()} zu benutzen.

Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.

@subsubheading Rückgabewerte

Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_list_processes, mysql_list_tables, mysql_list_fields, C API functions
@c German node mysql_list_processes
@subsubsection @code{mysql_list_processes()}

@findex @code{mysql_list_processes()}

@code{MYSQL_RES *mysql_list_processes(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt eine Ergebnismenge zurück, die die aktuellen Server-Threads
beschreibt. Das ist dieselbe Art von Information, die von @code{mysqladmin
processlist} oder einer @code{SHOW PROCESSLIST}-Anfrage zur Verfügung
gestellt wird.

Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.

@subsubheading Rückgabewerte

Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein
Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_list_tables, mysql_num_fields, mysql_list_processes, C API functions
@c German node mysql_list_tables
@subsubsection @code{mysql_list_tables()}

@findex @code{mysql_list_tables()}

@code{MYSQL_RES *mysql_list_tables(MYSQL *mysql, const char *wild)}

@subsubheading Beschreibung

Gibt eine Ergebnismenge zurück, die aus Tabellennamen in der aktuellen
Datenbank besteht, die mit einem einfachen regulären Ausdruck
übereinstimmen, der durch den @code{wild}-Parameter angegeben wird.
@code{wild} darf die Platzhalterzeichen @samp{%} oder @samp{_} enthalten
oder ein @code{NULL}-Zeiger sein, der mit allen Tabellen übereinstimmt. Der
Aufruf von @code{mysql_list_tables()} ist ähnlich der Ausführung der
Anfrage @code{SHOW tables [LIKE wild]}.

Sie müssen die Ergebnismenge mit @code{mysql_free_result()} freigeben.

@subsubheading Rückgabewerte

Eine @code{MYSQL_RES}-Ergebnismenge bei Erfolg. @code{NULL}, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_num_fields, mysql_num_rows, mysql_list_tables, C API functions
@c German node mysql_num_fields
@subsubsection @code{mysql_num_fields()}

@findex @code{mysql_num_fields()}
@findex @code{mysql_field_count()}

@code{unsigned int mysql_num_fields(MYSQL_RES *result)}

oder

@code{unsigned int mysql_num_fields(MYSQL *mysql)}

Die zweite Form funktioniert nicht bei MySQL-Version 3.22.24 oder neuer. Um
ein @code{MYSQL*}-Argument zu übergeben, müssen Sie statt dessen
@code{unsigned int mysql_field_count(MYSQL *mysql)} benutzen.

@subsubheading Beschreibung

Gibt die Anzahl von Spalten in einer Ergebnismenge zurück.

Beachten Sie, dass Sie die Anzahl von Spalten entweder durch einen Zeiger
auf die Ergebnismenge oder auf ein Verbindungs-Handle erhalten. Das
Verbindungs-Handle benutzen Sie, wenn @code{mysql_store_result()} oder
@code{mysql_use_result()}  @code{NULL} zurückgibt (und Sie daher keinen
Ergebnismengen-Zeiger haben). In diesem Fall können Sie
@code{mysql_field_count()} aufrufen, um festzustellen, ob
@code{mysql_store_result()} eine leere Ergebnismenge produziert haben
sollte oder nicht. Das erlaubt dem Client-Programm, die korrekten Aktionen
vorzunehmen, ohne wissen zu müssen, ob die Anfrage ein @code{SELECT}- (oder
@code{SELECT}-ähnliches) Statement war oder nicht. Das unten stehende
Beispiel zeigt, wie das gemacht wird.

@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.

@subsubheading Rückgabewerte

Eine vorzeichenlose Ganzzahl, die die Anzahl von Feldern in einer
Ergebnismenge darstellt.

@subsubheading Fehler

Keine.

@subsubheading Beispiel

@example
MYSQL_RES *ergebnis;
unsigned int anzahl_felder;
unsigned int anzahl_zeilen;

if (mysql_query(&mysql,anfrage_zeichenkette))
@{
    // FEHLER
@}
else // Anfrage erfolgreich, zurückgegebene Daten verarbeiten
@{
    ergebnis = mysql_store_result(&mysql);
    if (ergebnis)  // Es gibt Zeilen
    @{
        anzahl_felder = mysql_num_fields(ergebnis);
        // Zeilen abrufen, dann mysql_free_result(ergebnis) aufrufen
    @}
    else  // mysql_store_result() gab nichts zurück, hätte es das tun sollen?
    @{
        if (mysql_errno(&mysql))
	@{
           fprintf(stderr, "Fehler: %s\n", mysql_error(&mysql));
	@}
        else if (mysql_field_count(&mysql) == 0)
        @{
            // Anfrage gibt keine Daten zurück
            // (war kein SELECT)
            anzahl_zeilen = mysql_affected_rows(&mysql);
        @}
    @}
@}
@end example

Eine Alternative (wenn Sie WISSEN, dass Ihre Anfrage eine Ergebnismenge
hätte zurückgeben sollen) ist es, den @code{mysql_errno(&mysql)}-Aufruf
durch eine Prüfung zu ersetzen, ob @code{mysql_field_count(&mysql)} gleich
0 ist. Das passiert nur, wenn etwas schief lief.


@node mysql_num_rows, mysql_options, mysql_num_fields, C API functions
@c German node mysql_num_rows
@subsubsection @code{mysql_num_rows()}

@findex @code{mysql_num_rows()}

@code{my_ulonglong mysql_num_rows(MYSQL_RES *result)}

@subsubheading Beschreibung

Gibt die Anzahl von Zeilen in der Ergebnismenge zurück.

Die Benutzung von @code{mysql_num_rows()} hängt davon ab, ob Sie
@code{mysql_store_result()} oder @code{mysql_use_result()} benutzen, um die
Ergebnismenge zurückzugeben.. Wenn Sie @code{mysql_store_result()}
benutzen, kann @code{mysql_num_rows()} unmittelbar aufgerufen werden. Wenn
Sie @code{mysql_use_result()} benutzen, gibt @code{mysql_num_rows()} nicht
den richtigen Wert zurück, bis alle Zeilen in der Ergebnismenge abgerufen
wurden.

@subsubheading Rückgabewerte

Die Anzahl von Zeilen in der Ergebnismenge.

@subsubheading Fehler

Keine.


@node mysql_options, mysql_ping, mysql_num_rows, C API functions
@c German node mysql_options
@subsubsection @code{mysql_options()}

@findex @code{mysql_options()}

@code{int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)}

@subsubheading Beschreibung

Kann benutzt werden, um zusätzliche Optionen zu setzen und das Verhalten
einer Verbindung zu beeinflussen. Diese Funktion kann mehrfach aufgerufen
werden, um mehrere Optionen zu setzen.

@code{mysql_options()} sollte nach @code{mysql_init()} und vor
@code{mysql_connect()} oder @code{mysql_real_connect()} aufgerufen werden.

Das @code{option}-Argument ist die Option, die Sie setzen wollen. Das
@code{arg}-Argument ist der Wert für die Option. Wenn die Option eine
Ganzzahl ist, sollte @code{arg} auf den Wert der Ganzzahl zeigen.

Mögliche Optionswerte:

@multitable @columnfractions .25 .25 .5
@item @strong{Option} @tab @strong{Argumenttyp} @tab @strong{Funktion}
@item @code{MYSQL_OPT_CONNECT_TIMEOUT} @tab @code{unsigned int *} @tab Verbindungszeitüberschreitung (Timeout) in Sekunden.
@item @code{MYSQL_OPT_COMPRESS} @tab Unbenutzt @tab Das komprimierte Client-/Server-Protokoll verwenden.
@item @code{MYSQL_OPT_NAMED_PIPE} @tab Unbenutzt @tab Named Pipes benutzen, um sich mit einem MySQL-Server unter NT zu verbinden.
@item @code{MYSQL_INIT_COMMAND} @tab @code{char *} @tab Befehl, der beim Verbinden mit dem MySQL-Server ausgeführt werden soll. Wird beim erneuten Verbinden automatisch wieder ausgeführt.
@item @code{MYSQL_READ_DEFAULT_FILE} @tab @code{char *} @tab Optionen aus der benannten Optionsdatei einlesen anstelle von @file{my.cnf}.
@item @code{MYSQL_READ_DEFAULT_GROUP} @tab @code{char *} @tab Optionen aus der benannten Gruppe von @file{my.cnf} oder der Datei einlesen, die durch @code{MYSQL_READ_DEFAULT_FILE} angegeben wurde.
@end multitable

Beachten Sie, dass die Gruppe @code{client} immer gelesen wird, wenn Sie
@code{MYSQL_READ_DEFAULT_FILE} oder @code{MYSQL_READ_DEFAULT_GROUP}
benutzen.

Die angegebene Gruppe in der Optionsdatei kann folgende Optionen enthalten:

@multitable @columnfractions .3 .7
@item @code{connect_timeout} @tab Zeitüberschreitung (Timeout) für die
Verbindung in Sekunden. Unter Linux wird dieser Wert zusätzlich für die
Wartezeit auf die erste Antwort vom Server benutzt.
@item @code{compress} @tab Das komprimierte Client-/Server-Protokoll
benutzen.
@item @code{database} @tab Mit dieser Datenbank verbinden, wenn im
Verbindungsbefehl keine Datenbank angegeben wurde.
@item @code{debug} @tab Debug-Optionen.
@item @code{host} @tab Vorgabemäßiger Hostname.
@item @code{init-commund} @tab Befehl, der bei der Verbindung zum
MySQL-Server ausgeführt wird. Wird automatisch beim erneuten Verbinden
erneut ausgeführt.
@item @code{interactive-timeout} @tab Dasselbe wie die Angabe von
@code{CLIENT_INTERACTIVE} für @code{mysql_real_connect()}.
@xref{mysql_real_connect}.
@item @code{password} @tab Vorgabemäßiges Passwort.
@item @code{pipe} @tab Named Pipes benutzen, um sich mit einem MySQL-Server unter NT zu verbinden.
@item @code{port} @tab Vorgabemäßige Port-Nummer.
@item @code{return-found-rows} @tab Weist @code{mysql_info()} an, gefundene
Zeilen anstelle von aktualisierten Zeilen zurückzugeben, wenn @code{UPDATE}
benutzt wird.
@item @code{socket} @tab Vorgabemäßige Socket-Nummer.
@item
@item @code{user} @tab Vorgabemäßiger Benutzer.
@end multitable

Beachten Sie, dass @code{timeout} durch @code{connect_timeout} ersetzt
wurde. Dennoch wird @code{timeout} noch für eine Weile funktionieren.

Weitere Informationen über Optionsdateien finden Sie unter
@ref{Option files}.

@subsubheading Rückgabewerte

0 bei Erfolg. Nicht-0, wenn Sie eine unbekannte Option verwenden.

@subsubheading Beispiel

@example
MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_OPT_COMPRESS,0);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"odbc");
if (!mysql_real_connect(&mysql,"host","benutzer","passwort","datenbank",0,NULL,0))
@{
    fprintf(stderr, "Keine Verbindung zur Datenbank: Fehler: %s\n",
          mysql_error(&mysql));
@}
@end example

Im obigen Beispiel wird der Client angewiesen, das komprimierte
Client-/Server-Protokoll zu benutzen und zusätzliche Optionen aus dem
@code{odbc}-Abschnitt in @code{my.cnf} zu lesen.


@node mysql_ping, mysql_query, mysql_options, C API functions
@c German node mysql_ping
@subsubsection @code{mysql_ping()}

@findex @code{mysql_ping()}

@code{int mysql_ping(MYSQL *mysql)}

@subsubheading Beschreibung

Prüft, ob die Verbindung zum Server funktioniert oder nicht. Wenn diese weg
ist, wird automatisch eine erneute Verbindung versucht.

Diese Funktion kann von Clients benutzt werden, die für lange Zeit im
Leerlauf laufen, um zu prüfen, ob der Server die Verbindung geschlossen
hat, und sich bei Bedarf erneut zu verbinden.

@subsubheading Rückgabewerte

0, wenn der Server da ist. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_query, mysql_real_connect, mysql_ping, C API functions
@c German node mysql_query
@subsubsection @code{mysql_query()}

@findex @code{mysql_query()}

@code{int mysql_query(MYSQL *mysql, const char *anfrage)}

@subsubheading Beschreibung
Führt die SQL-Anfrage aus, auf die durch die NULL-begrenzte Zeichenkette
@code{anfrage} gezeigt wird. Die Anfrage muss aus einem einzelnen
SQL-Statement bestehen. Sie dürfen kein Semikolon (@samp{;}) oder @code{\g}
zum Statement hinzufügen.

@code{mysql_query()} kann nicht für Anfragen benutzt werden, die Binärdaten
enthalten. Hierfür sollten Sie statt dessen @code{mysql_real_query()}
benutzen. (Binärdaten können das @samp{\0}-Zeichen enthalten, was
@code{mysql_query()} als Ende der Anfrage-Zeichenkette interpretiert.)

Wenn Sie wissen wollen, ob die Anfrage eine Ergebnismenge zurückgeben
sollte oder nicht, können Sie @code{mysql_field_count()} benutzen, um
hierauf zu prüfen. @xref{mysql_field_count, , @code{mysql_field_count}}.

@subsubheading Rückgabewerte

0, wenn die Anfrage erfolgreich war. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_real_connect, mysql_real_escape_string, mysql_query, C API functions
@c German node mysql_real_connect
@subsubsection @code{mysql_real_connect()}

@findex @code{mysql_real_connect()}

@code{MYSQL *mysql_real_connect(MYSQL *mysql, const char *host,
                          const char *user, const char *passwd, const char *db,
                          unsigned int port, const char *unix_socket,
                          unsigned int client_flag)}

@subsubheading Beschreibung

@code{mysql_real_connect()} versucht, eine Verbindung zu einer
MySQL-Datenbankmaschine aufzubauen, die auf @code{host} läuft.
@code{mysql_real_connect()} muss erfolgreich verlaufen sein, bevor Sie
irgend eine andere API-Funktion ausführen können, mit Ausnahme von
@code{mysql_get_client_info()}.

Die Parameter werden wie folgt angegeben:

@itemize @bullet
@item
Der erste Parameter sollte die Adresse einer existierenden
@code{MYSQL}-Struktur sein. Vor dem Aufruf von @code{mysql_real_connect()}
müssen Sie @code{mysql_init()} aufrufen, um die @code{MYSQL}-Struktur zu
initialisieren. Sie können viele der Verbindungsoptionen mit dem
@code{mysql_options()}-Aufruf ändern. @xref{mysql_options}.

@item
Der Wert von @code{host} kann entweder ein Hostname oder eine IP-Adresse
sein. Wenn @code{host} @code{NULL} oder die Zeichenkette @code{"localhost"}
ist, wird eine Verbindung zum lokalen Host angenommen. Wenn das
Betriebssystem Sockets (Unix) oder Named Pipes (Windows NT) unterstützt,
werden diese statt TCP/IP benutzt, um sich mit dem Server zu verbinden.

@item
Der @code{user}-Parameter enthält die MySQL-Login-Benutzerkennung. Wenn
@code{user} @code{NULL} ist, wird der aktuelle Benutzer angenommen. Unter
Unix ist das der aktuelle Login-Name. Unter Windows-ODBC muss der aktuelle
Benutzername explizit angegeben werden. @xref{ODBC administrator}.

@item
Der @code{passwd}-Parameter enthält das Passwort für @code{user}. Wenn
@code{passwd} @code{NULL} ist, werden nur Einträge in der
@code{user}-Tabelle für Benutzer auf Übereinstimmung überprüft, die ein
leeres Passwort-Feld haben. Das erlaubt dem Datenbank-Administrator, das
MySQL-Berechtigungssystem so einzurichten, dass Benutzer unterschiedliche
Berechtigungen haben, je nachdem, ob sie ein Passwort angegeben haben oder
nicht.

HINWEIS: Versuchen Sie nicht, dass Passwort zu verschlüsseln, bevor Sie
@code{mysql_real_connect()} aufrufen. Die Passwortverschlüsselung wird
automatisch durch die Client-API gehandhabt.

@item
@code{db} ist der Datenbankname. Wenn @code{db} nicht @code{NULL} ist,
wird die vorgabemäßige Datenbank für die Verbindung auf diesen Wert
gesetzt.

@item
Wenn @code{port} nicht 0 ist, wird dieser Wert als Port-Nummer für die
TCP/IP-Verbindung benutzt. Beachten Sie, dass der @code{host}-Parameter den
Verbindungstyp festlegt.

@item
Wenn @code{unix_socket} nicht @code{NULL} ist, legt die Zeichenkette den
Socket oder die Named Pipe fest, die benutzt werden sollen. Beachten Sie,
dass der @code{host}-Parameter den Verbindungstyp festlegt.

@item
Der Wert von @code{client_flag} ist üblicherweise 0, kann aber unter sehr
speziellen Umständen auf eine Kombination folgender Flags gesetzt werden:

@multitable @columnfractions .25 .7
@item @strong{Flag-Name}       @tab @strong{Flag-Bedeutung}
@item @code{CLIENT_COMPRESS}   @tab Komprimiertes Protokoll benutzen.
@item @code{CLIENT_FOUND_ROWS} @tab Die Anzahl gefundener
(übereinstimmender) Zeilen zurückgeben, nicht die Anzahl betroffener
Zeilen.
@item @code{CLIENT_IGNORE_SPACE} @tab Leerzeichen nach Funktionsnamen
zulassen. Macht alle Funktionsnamen zu reservierten Wörter.
@item @code{CLIENT_INTERACTIVE} @tab @code{interactive_timeout} Sekunden
zulassen (anstelle von @code{wait_timeout} Sekunden) von Inaktivität, bevor
die Verbindung geschlossen wird.
@item @code{CLIENT_NO_SCHEMA}  @tab Die
@code{datenbank.tabelle.spalte}-Syntax nicht zulassen. Das ist für ODBC.
Der Flag veranlasst den Parser, einen Fehler zu erzeugen, wenn Sie diese
Syntax benutzen, was für die Fehlersuche in einigen ODBC-Programmen
hilfreich ist.
@item @code{CLIENT_ODBC}       @tab Der Client ist ein ODBC-Client. Das
ändert
@item @code{CLIENT_SSL}		@tab SSL benutzen (verschlüsseltes Protokoll).
@end multitable
@end itemize

@subsubheading Rückgabewerte

Ein @code{MYSQL*}-Verbindungs-Handle, wenn die Verbindung erfolgreich war,
@code{NULL}, wenn die Verbindung nicht erfolgreich war. Bei einer
erfolgreichen Verbindung ist der Rückgabewert derselbe wie der Wert des
ersten Parameters, es sei denn, Sie übergeben für diesen Parameter
@code{NULL}.

@subsubheading Fehler

@table @code
@item CR_CONN_HOST_ERROR
Verbindung zum MySQL-Server fehlgeschlagen.

@item CR_CONNECTION_ERROR
Verbindung zum lokalen MySQL-Server fehlgeschlagen.

@item CR_IPSOCK_ERROR
IP-Socket konnte nicht erzeugt werden.

@item CR_OUT_OF_MEMORY
Kein Speicher mehr.

@item CR_SOCKET_CREATE_ERROR
Unix-Socket konnte nicht erzeugt werden.

@item CR_UNKNOWN_HOST
IP-Adresse für den Hostnamen konnte nicht gefunden werden.

@item CR_VERSION_ERROR
Eine Protokollunverträglichkeit resultierte aus dem Versuch, sich mit einer
Client-Bibliothek mit einem Server zu verbinden, die eine andere
Protokollversion benutzt. Das kann passieren, wenn Sie eine sehr alte
Client-Bibliothek benutzen und sich mit einem neuen Server verbinden, der
nicht mit der @code{--old-protocol}-Option gestartet wurde.

@item CR_NAMEDPIPEOPEN_ERROR
Named Pipe unter Windows konnte nicht erzeugt werden.

@item CR_NAMEDPIPEWAIT_ERROR
Fehler beim Warten auf eine Named Pipe unter Windows.

@item CR_NAMEDPIPESETSTATE_ERROR
Pipe-Handler unter Windows konnte nicht erlangt werden.

@item CR_SERVER_LOST
Wenn @code{connect_timeout} > 0 ist und die Verbindung zum Server länger
als @code{connect_timeout} benötigte, oder wenn der Server während der
Ausführung von @code{init-command} starb.

@end table

@subsubheading Beispiel

@example
MYSQL mysql;

mysql_init(&mysql);
mysql_options(&mysql,MYSQL_READ_DEFAULT_GROUP,"your_prog_name");
if (!mysql_real_connect(&mysql,"host","benutzer","passwort","datenbank",0,NULL,0))
@{
    fprintf(stderr, "Verbindung zur Datenbank fehlgeschlagen: Fehler: %s\n",
          mysql_error(&mysql));
@}
@end example

Wenn Sie @code{mysql_options()} benutzen, liest die MySQL-Bibliothek die
@code{[client]}- und @code{ihr_programm_name}-Abschnitte in der
@code{my.cnf}-Datei. Das stellt sicher, dass Ihr Programm funktioniert,
selbst wenn jemand MySQL auf Nicht-Standard-Weise eingerichtet hat.

Beachten Sie, dass @code{mysql_real_connect()} beim Verbinden den
@code{reconnect}-Flag (Teil der MySQL-Struktur) auf einen Wert von @code{1}
setzt. Dieser Flag gibt an, dass ein erneuter Verbindungsversuch zum Server
gemacht wird, bevor aufgegeben wird, wenn eine Anfrage wegen einer verloren
gegangenen Verbindung nicht ausgeführt werden kann.


@node mysql_real_escape_string, mysql_real_query, mysql_real_connect, C API functions
@c German node mysql_real_escape_string
@subsubsection @code{mysql_real_escape_string()}

@findex @code{mysql_real_escape_string()}

@code{unsigned int mysql_real_escape_string(MYSQL *mysql, char *nach, const char *von, unsigned int laenge)}

@subsubheading Beschreibung

Diese Funktion wird benutzt, um eine zulässige SQL-Zeichenkette zu
erzeugen, die Sie in einem SQL-Statement benutzen können.
@xref{String syntax}.

Die Zeichenkette in @code{von} wird in eine escapete SQL-Zeichenkette
kodiert, wobei der aktuelle Zeichensatz der Verbindung berücksichtigt wird.
Das Ergebnis wird in @code{nach} platziert und ein Null-Byte am Ende
angefügt. Kodierte Zeichen sind @code{NUL} (ASCII 0), @samp{\n}, @samp{\r},
@samp{\}, @samp{'}, @samp{"} und Control-Z (@pxref{Literals}).

Die Zeichenkette, auf die von @code{von} gezeigt wird, muss @code{laenge}
Bytes lang sein. Sie müssen den @code{nach}-Puffer so zuweisen, dass er
mindestens @code{laenge*2+1} Bytes lang ist. (Im schlimmsten Fall muss
jedes Zeichen mit zwei Bytes kodiert werden, und Sie brauchen Platz für das
Null-Byte am Ende.) Wenn @code{mysql_escape_string()} zurückgibt, sind die
Inhalte von @code{nach} eine Null-begrenzte Zeichenkette. Der Rückgabewert
ist die Länge der kodierten Zeichenkette, ohne das Null-Zeichen am Ende.

@subsubheading Beispiel

@example
char anfrage[1000],*end;

end = strmov(anfrage,"INSERT INTO tabelle values(");
*end++ = '\'';
end += mysql_real_escape_string(&mysql, end,"Was is'n das?",12);
*end++ = '\'';
*end++ = ',';
*end++ = '\'';
end += mysql_real_escape_string(&mysql, end,"Binärdaten: \0\r\n",17);
*end++ = '\'';
*end++ = ')';

if (mysql_real_query(&mysql,anfrage,(unsigned int) (end - anfrage)))
@{
   fprintf(stderr, "Einfügen der Zeile fehlgeschlagen, Fehler: %s\n",
           mysql_error(&mysql));
@}
@end example

Die im Beispiel benutzte @code{strmov()}-Funktion ist in der
@code{mysqlclient}-Bibliothek enthalten und funktioniert wie
@code{strcpy()}, gibt aber einen Zeiger auf Null am Ende des ersten
Parameters zurück.

@subsubheading Rückgabewerte

Die Länge des Wertes in @code{nach}, ohne das Null-Zeichen am Ende.

@subsubheading Fehler

Keine.


@node mysql_real_query, mysql_reload, mysql_real_escape_string, C API functions
@c German node mysql_real_query
@subsubsection @code{mysql_real_query()}

@findex @code{mysql_real_query()}

@code{int mysql_real_query(MYSQL *mysql, const char *anfrage, unsigned int laenge)}

@subsubheading Beschreibung

Führt die SQL-Anfrage aus, auf die von @code{anfrage} gezeigt wird, was
eine @code{laenge} Bytes lange Zeichenkette sein sollte. Die0 Anfrage muss
aus einem einzelnen SQL-Statement bestehen. Sie dürfen kein Semikolon
(@samp{;}) oder @code{\g} zum Statement hinzufügen.

Sie @emph{müssen} @code{mysql_real_query()} statt @code{mysql_query()} für
Anfragen benutzen, die Binärdaten enthalten, weil Binärdaten das
@samp{\0}-Zeichen enthalten können. Ausserdem ist @code{mysql_real_query()}
schneller als @code{mysql_query()}, weil es in der Anfragezeichenkette
nicht @code{strlen()} aufruft.

Wenn Sie wissen wollen, ob die Anfrage eine Ergebnismenge zurückgeben
sollte oder nicht, können Sie hierfür @code{mysql_field_count()} benutzen.
@xref{mysql_field_count, @code{mysql_field_count}}.

@subsubheading Rückgabewerte

0, wenn die Anfrage erfolgreich war. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_reload, mysql_row_seek, mysql_real_query, C API functions
@c German node mysql_reload
@subsubsection @code{mysql_reload()}

@findex @code{mysql_reload()}

@code{int mysql_reload(MYSQL *mysql)}

@subsubheading Beschreibung

Weist den MySQL-Server an, die Berechtigungstabellen neu zu laden. Der
verbundene Benutzer muss die @strong{reload}-Berechtigung haben.

Diese Funktion ist veraltet. Vorzugsweise sollten Sie @code{mysql_query()}
benutzen, um statt dessen ein SQL-@code{FLUSH PRIVILEGES}-Statement
auszuführen.

@subsubheading Rückgabewerte

0 bei Erfolg. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_row_seek, mysql_row_tell, mysql_reload, C API functions
@c German node mysql_row_seek
@subsubsection @code{mysql_row_seek()}

@findex @code{mysql_row_seek()}

@code{MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES *ergebnis, MYSQL_ROW_OFFSET offset)}

@subsubheading Beschreibung
Setzt den Zeilencursor auf eine beliebige Zeile in einer
Anfrageergebnismenge. Dafür ist erforderlich, dass die
Ergebnismengenstruktur das gesamte Ergebnis der Anfrage enthält, so dass
@code{mysql_row_seek()} nur in Verbindung mit @code{mysql_store_result()}
benutzt werden kann, nicht mit @code{mysql_use_result()}.

Der Offset sollte ein Wert sein, der von einem Aufruf von
@code{mysql_row_tell()} oder @code{mysql_row_seek()} zurückgegeben wird.
Dieser Wert ist nicht einfach eine Zeilennummer; wenn Sie eine Zeile
innerhalb einer Ergebnismenge mittels einer Zeilennummer suchen wollen,
benutzen Sie statt dessen @code{mysql_data_seek()}.

@subsubheading Rückgabewerte

Der vorherige Wert des Zeilencursors. Dieser Wert kann an einen
nachfolgenden Aufruf von @code{mysql_row_seek()} übergeben werden.

@subsubheading Fehler

Keine.


@node mysql_row_tell, mysql_select_db, mysql_row_seek, C API functions
@c German node mysql_row_tell
@subsubsection @code{mysql_row_tell()}

@findex @code{mysql_row_tell()}

@code{MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES *ergebnis)}

@subsubheading Beschreibung

Gibt die aktuelle Position des Zeilencursors für das letzte
@code{mysql_fetch_row()} zurück. Dieser Wert kann als Argument für
@code{mysql_row_seek()} benutzt werden.

Sie sollten @code{mysql_row_tell()} nur nach @code{mysql_store_result()},
nicht nach @code{mysql_use_result()} benutzen.

@subsubheading Rückgabewerte

Der aktuelle Offset des Zeilencursors.

@subsubheading Fehler

Keine.


@node mysql_select_db, mysql_shutdown, mysql_row_tell, C API functions
@c German node mysql_select_db
@subsubsection @code{mysql_select_db()}

@findex @code{mysql_select_db()}

@code{int mysql_select_db(MYSQL *mysql, const char *db)}

@subsubheading Beschreibung

Führt dazu, dass die Datenbank, die durch @code{db} angegeben wird, die
vorgabemäßige (aktuelle) Datenbank auf der von @code{mysql} angegebenen
Verbindung wird. Bei nachfolgenden Anfragen ist diese Datenbank die Vorgabe
für Tabellenverweise, die nicht explizit einen Datenbank-Spezifizierer
enthalten.

@code{mysql_select_db()} schlägt fehl, wenn der verbundene Benutzer keine
Zugriffsrechte auf die Datenbank hat.

@subsubheading Rückgabewerte

0 bei Erfolg. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_shutdown, mysql_stat, mysql_select_db, C API functions
@c German node mysql_shutdown
@subsubsection @code{mysql_shutdown()}

@findex @code{mysql_shutdown()}

@code{int mysql_shutdown(MYSQL *mysql)}

@subsubheading Beschreibung

Führt dazu, dass der Datenbankserver herunter fährt. Der verbundene
Benutzer muss die @strong{shutdown}-Berechtigung haben.

@subsubheading Rückgabewerte

0 bei Erfolg. Nicht-0, wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_stat, mysql_store_result, mysql_shutdown, C API functions
@c German node mysql_stat
@subsubsection @code{mysql_stat()}

@findex @code{mysql_stat()}

@code{char *mysql_stat(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt eine Zeichenkette zurück, die Informationen enthält, die ähnlich denen
sind, die vom @code{mysqladmin status}-Befehl zur Verfügung gestellt
werden. Das schließt die Betriebszeit (Uptime) in Sekunden und die Anzahl
laufender Threads, Anfragen (Questions), Neuladen (Reloads) und offener
Tabellen ein.

@subsubheading Rückgabewerte

Eine Zeichenkette, die den Serverstatus beschreibt. @code{NULL}, wenn ein
Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_store_result, mysql_thread_id, mysql_stat, C API functions
@c German node mysql_store_result
@subsubsection @code{mysql_store_result()}

@findex @code{mysql_store_result()}

@code{MYSQL_RES *mysql_store_result(MYSQL *mysql)}

@subsubheading Beschreibung

Sie müssen @code{mysql_store_result()} oder @code{mysql_use_result()} für
jede Anfrage aufrufen, die erfolgreich Daten abruft (@code{SELECT},
@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}).

Für andere Anfragen müssen Sie @code{mysql_store_result()} oder
@code{mysql_use_result()} nicht aufrufen, es schadet aber auch nicht, noch
führt es zu wahrnehmbaren Performance-Störungen, wenn Sie
@code{mysql_store_result()} in jedem Fall aufrufen. Sie können feststellen,
ob die Anfrage keine Ergebnismenge hatte, wenn Sie prüfen, ob
@code{mysql_store_result()} 0 zurückgibt (mehr darüber später).

Wenn Sie wissen wollen, ob die Anfrage eine Ergebnismenge zurückgeben
sollte oder nicht, können Sie hierfür @code{mysql_field_count()} benutzen.
@xref{mysql_field_count, @code{mysql_field_count}}.

@code{mysql_store_result()} liest das gesamte Ergebnis einer Anfrage zum
Client ein, weist eine @code{MYSQL_RES}-Struktur zu und platziert das
Ergebnis in diese Struktur.

@code{mysql_store_results()} gibt einen NULL-Zeiger zurück, wenn die
Anfrage keine Ergebnismenge zurückgab (wenn die Anfrage zum Beispiel ein
@code{INSERT}-Statement war).

@code{mysql_store_results()} gibt auch einen NULL-Zeiger zurück, wenn das
Lesen der Ergebnismenge fehlschlug. Sie können prüfen, ob Sie einen Fehler
erhielten, wenn @code{mysql_error()} keinen NULL-Zeiger zurückgibt, wenn
@code{mysql_errno()} ungleich 0 zurückgibt oder wenn
@code{mysql_field_count()} ungleich 0 zurückgibt.

Eine leere Ergebnismenge wird zurückgegeben, wenn keine Zeilen
zurückgegeben werden. (Eine leere Ergebnismenge unterscheidet sich als
Rückgabewert von einem NULL-Zeiger.)

Nachdem Sie erst einmal @code{mysql_store_result()} aufgerufen und ein
Ergebnis erhalten haben, das kein NULL-Zeiger ist, können Sie
@code{mysql_num_rows()} aufrufen, um herauszufinden, wie viele Zeilen es in
der Ergebnismenge gibt.

Sie können @code{mysql_fetch_row()} aufrufen, um Zeilen aus der
Ergebnismenge zu holen, oder @code{mysql_row_seek()} und
@code{mysql_row_tell()}, um die aktuelle Zeilenposition innerhalb der
Ergebnismenge zu erhalten oder zu setzen.

Sie müssen @code{mysql_free_result()} aufrufen, wenn Sie mit der
Ergebnismenge fertig sind.

@xref{NULL mysql_store_result, , @code{NULL mysql_store_result()}}.

@subsubheading Rückgabewerte

Eine @code{MYSQL_RES}-Ergebnisstruktur mit den Ergebnissen. @code{NULL},
wenn ein Fehler auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_OUT_OF_MEMORY
Kein Speicher mehr.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table


@node mysql_thread_id, mysql_use_result, mysql_store_result, C API functions
@c German node mysql_thread_id
@subsubsection @code{mysql_thread_id()}

@findex @code{mysql_thread_id()}

@code{unsigned long mysql_thread_id(MYSQL *mysql)}

@subsubheading Beschreibung

Gibt die Thread-Kennung der aktuellen Verbindung zurück. Der Wert kann als
Argument für @code{mysql_kill()} benutzt werden, um den Thread zu töten.

Wenn die Verbindung verloren ging und Sie sich mit @code{mysql_ping()}
erneut verbinden, ändert sich die Thread-Kennung. Das heißt, dass Sie
nicht die Thread-Kennung holen und für spätere Benutzung speichern sollten.
Sie sollten sie holen, wenn Sie sie benötigen.

@subsubheading Rückgabewerte

Die Thread-Kennung der aktuellen Verbindung.

@subsubheading Fehler

Keine.


@node mysql_use_result,  , mysql_thread_id, C API functions
@c German node mysql_use_result
@subsubsection @code{mysql_use_result()}

@findex @code{mysql_use_result()}

@code{MYSQL_RES *mysql_use_result(MYSQL *mysql)}

@subsubheading Beschreibung

Sie müssen @code{mysql_store_result()} oder @code{mysql_use_result()} für
jede Anfrage aufrufen, die erfolgreich Daten abruft (@code{SELECT},
@code{SHOW}, @code{DESCRIBE}, @code{EXPLAIN}).

@code{mysql_use_result()} initiiert einen Ergebnismengen-Abruf, aber liest
die Ergebnismenge nicht tatsächlich in den Client wie
@code{mysql_store_result()}. Statt dessen muss jede Zeile individuell
abgerufen werden, indem Aufrufe von @code{mysql_fetch_row()} durchgeführt
werden. Das liest das Ergebnis einer Anfrage direkt vom Server, ohne es in
einer temporären Tabelle oder einem lokalen Puffer zu speichern, was
manchmal schneller ist und viel weniger Speicher benutzt als
@code{mysql_store_result()}. Dem Client wird nur Speicher für die aktuelle
Zeile zugewiesen sowie ein Kommunikationspuffer, der bis zu
@code{max_allowed_packet} Bytes Groß werden kann.

Auf der anderen Seite sollten Sie @code{mysql_use_result()} nicht benutzen,
wenn Sie viele Verarbeitungen für jede Zeile auf der Client-Seite
durchführen oder wenn die Ausgabe auf den Bildschirm geschickt wird, auf
dem der Benutzer @code{^S} (stop scroll) eingeben kann. Das bindet den
Server und verhindert, dass andere Threads irgend welche Tabellen
aktualisieren können, von denen gerade Daten geholt werden.

Wenn Sie @code{mysql_use_result()} benutzen, müssen Sie
@code{mysql_fetch_row()} ausführen, bis ein @code{NULL}-Wert zurückgegeben
wird, denn ansonsten werden die nicht geholten Zeilen als Teil der
Ergebnismenge bei Ihrer nächsten Anfrage zurückgegeben. Die C-API gibt den
Fehler @code{Commands out of sync; You can't run this command now} aus,
wenn Sie das vergessen!

Sie können @code{mysql_data_seek()}, @code{mysql_row_seek()},
@code{mysql_row_tell()}, @code{mysql_num_rows()} oder
@code{mysql_affected_rows()} nicht bei einem Ergebnis verwenden, das von
@code{mysql_use_result()} zurückgegeben wird. Ausserdem dürfen Sie keine
anderen Anfragen absetzen, bis @code{mysql_use_result()} beendet ist.
(Nachdem Sie alle Zeilen abgeholt haben, wird @code{mysql_num_rows()}
jedoch exakt die Anzahl der geholten Zeilen zurückgeben.)

Sie müssen @code{mysql_free_result()} aufrufen, wenn Sie mit der
Ergebnismenge fertig sind.

@subsubheading Rückgabewerte

Eine @code{MYSQL_RES}-Ergebnisstruktur. @code{NULL}, wenn ein Fehler
auftrat.

@subsubheading Fehler

@table @code
@item CR_COMMANDS_OUT_OF_SYNC
Befehle wurden nicht in der korrekten Reihenfolge ausgeführt.
@item CR_OUT_OF_MEMORY
Kein Speicher mehr.
@item CR_SERVER_GONE_ERROR
Der MySQL-Server ist weg.
@item CR_SERVER_LOST
Die Verbindung zum Server ging während der Anfrage verloren.
@item CR_UNKNOWN_ERROR
Ein unbekannter Fehler trat auf.
@end table

@node C Thread functions, C Embedded Server func, C API functions, C
@c German node C-Thread-Funktionen
@subsection C-Threaded-Funktionsbeschreibungen

Sie benötigen folgende Funktionen, wenn Sie einen threaded Client erstellen
wollen. @xref{Threaded clients}.


@menu
* my_init::                     
* mysql_thread_init::           
* mysql_thread_end::            
* mysql_thread_safe::           
@end menu

@node my_init, mysql_thread_init, C Thread functions, C Thread functions
@c German node my_init()
@subsubsection @code{my_init()}

@findex @code{my_init()}

@subsubheading Beschreibung

Diese Funktion muss einmal im Programm aufgerufen werden, bevor Sie irgend
eine MySQL-Funktion aufrufen. Sie initialisiert einige globale Variablen,
die MySQL braucht. Wenn Sie eine Thread-sichere Client-Bibliothek benutzen,
wird diese ebenfalls @code{mysql_thread_init()} für diesen Thread aufrufen.

Diese Funktion wird automatisch von @code{mysql_init()},
@code{mysql_server_init()} und @code{mysql_connect()} aufgerufen.

@subsubheading Rückgabewerte

Keine.

@node mysql_thread_init, mysql_thread_end, my_init, C Thread functions
@c German node mysql_thread_init()
@subsubsection @code{mysql_thread_init()}

@findex @code{mysql_thread_init()}

@subsubheading Beschreibung

Diese Funktion muss für jeden erzeugten Thread aufgerufen werden, um
Thread-spezifische Variablen zu initialisieren.

Diese Funktion wird automatisch von @code{my_init()} und
@code{mysql_connect()} aufgerufen.

@subsubheading Rückgabewerte

Keine.

@node mysql_thread_end, mysql_thread_safe, mysql_thread_init, C Thread functions
@c German node mysql_thread_end()
@subsubsection @code{mysql_thread_end()}

@findex @code{mysql_thread_end()}

@subsubheading Beschreibung

Diese Funktion muss vor dem Aufruf von @code{pthread_exit()} aufgerufen
werden, um den von @code{mysql_thread_init()} zugewiesenen Speicher
freizusetzen.

Beachten Sie, dass diese Funktion @strong{nicht automatisch} von der
Client-Bibliothek aufgerufen wird. Sie muss explizit aufgerufen werden, um
Speicherlecks zu vermeiden.

@subsubheading Rückgabewerte

Keine.

@node mysql_thread_safe,  , mysql_thread_end, C Thread functions
@c Arjen note: new @node 2002-04-19, please translate text!
@subsubsection @code{mysql_thread_safe()}

@findex @code{mysql_thread_safe()}

@code{unsigned int mysql_thread_safe(void)}

@subsubheading Description

This function indicates whether the client is compiled as thread safe.

@subsubheading Return Values

1 is the client is thread safe, 0 otherwise.

@node C Embedded Server func, C API problems, C Thread functions, C
@c German node C-Embedded-Server-Funktionen
@subsection C-Embedded-Server-Funktionsbeschreibungen

Sie müssen folgende Funktionen benutzen, wenn Sie wollen, dass Ihre
Applikation gegen die eingebettete MySQL-Server-Bibliothek gelinkt werden
kann. @xref{libmysqld}.

Wenn das Programm mit @code{-lmysqlclient} anstelle von @code{-lmysqld}
gelinkt wird, tun diese Funktionen nicht. Das ermöglicht die Auswahl
zwischen der Benutzung des eingebetteten MySQL-Servers und eines
Standalone-Servers, ohne irgend welchen Code zu verändern.


@menu
* mysql_server_init::           
* mysql_server_end::            
@end menu

@node mysql_server_init, mysql_server_end, C Embedded Server func, C Embedded Server func
@c German node mysql_server_init()
@subsubsection @code{mysql_server_init()}

@findex @code{mysql_server_init()}

@code{void mysql_server_init(int argc, const char **argv, const char **groups)}

@subsubheading Beschreibung

Diese Funktion @strong{muss} einmal im Programm aufgerufen werden, bevor
irgend eine andere MySQL-Funktion aufgerufen wird. Sie startet den Server
und initialisiert jegliche Subsysteme (@code{mysys}, InnoDB usw.), die der
Server benutzt. Wenn diese Funktion nicht aufgerufen wird, stürzt das
Programm ab.

Die @code{argc}- und @code{argv}-Argumente sind analog zu den Argumenten
für @code{main()}. Das erste Element von @code{argv} wird ignoriert (es
enthält typischerweise den Programmnamen). Aus Bequemlichkeitsgründen kann
@code{argc} @code{0} sein, wenn es keine Kommandozeilenargumente für den
Server gibt.

Die @code{NULL}-begrenzte Liste von Zeichenketten in @code{groups} wählt
aus, welche Gruppen in den Optionsdateien aktiv sind.
@xref{Option files}. Aus Bequemlichkeitsgründen kann @code{groups}
@code{NULL} sein. In diesem Fall ist die @code{[server]}-Gruppe aktiv.

@subsubheading Beispiel

@example
#include <mysql.h>
#include <stdlib.h>

static char *server_args[] = @{
  "Mein Programm",       /* Diese Zeichenkette ist unbenutzt */
  "--datadir=.",
  "--set-variable=key_buffer_size=32M"
@};
static char *server_groups[] = @{
  "server",
  "Dieser_Programm_SERVER",
  (char *)NULL
@};

int main(void) @{
  mysql_server_init(sizeof(server_args) / sizeof(char *),
                    server_args, server_groups);

  /* Hier können Sie irgend welche MySQL-API-Funktionen benutzen */

  mysql_server_end();

  return EXIT_SUCCESS;
@}
@end example

@subsubheading Rückgabewerte

Keine.

@node mysql_server_end,  , mysql_server_init, C Embedded Server func
@c German node mysql_server_end()
@subsubsection @code{mysql_server_end()}

@findex @code{mysql_server_end()}

@subsubheading Beschreibung

Diese Funktion @strong{muss} einmal im Programm nach allen anderen
MySQL-Funktionen aufgerufen werden. Sie fährt den eingebetteten Server
herunter.

@subsubheading Rückgabewerte

Keine.

@node C API problems, Building clients, C Embedded Server func, C
@c German node C-API-Probleme
@subsection Häufige Fragen und Probleme bei der Benutzung der C-API

@tindex @code{mysql_query()}
@tindex @code{mysql_store_result()}



@menu
* NULL mysql_store_result::     
* Query results::               
* Getting unique ID::           
* C API linking problems::      
@end menu

@node NULL mysql_store_result, Query results, C API problems, C API problems
@c German node NULL mysql_store_result
@subsubsection Warum gibt @code{mysql_store_result()} manchmal @code{NULL} zurück, nachdem @code{mysql_query()} Erfolg zurückgegeben hat?

@code{mysql_store_result()} kann @code{NULL} zurückgeben, auch nach einem
erfolgreichen Aufruf von @code{mysql_query()}. Wenn das passiert, bedeutet
das, dass eine der folgenden Bedingungen eingetreten ist:

@itemize @bullet
@item
Es gab einen @code{malloc()}-Fehler (zum Beispiel, wenn die Ergebnismenge
zu Groß war).

@item
Die Daten konnten nicht gelesen werden (ein Fehler mit der Verbindung trat
auf).

@item
Die Anfrage gab keine Daten zurück (sie war zum Beispiel ein @code{INSERT},
@code{UPDATE} oder @code{DELETE}).
@end itemize

Sie können jederzeit prüfen, ob das Statement eine leere Ergebnismenge
geliefert haben sollte oder nicht, indem Sie @code{mysql_field_count()}
aufrufen. Wenn @code{mysql_field_count()} 0 zurückliefert, ist das Ergebnis
leer und die letzte Anfrage war ein Statement, die keine Rückgabewerte
liefert (zum Beispiel ein @code{INSERT} oder ein @code{DELETE}). Wenn
@code{mysql_field_count()} einen Nicht-0-Wert zurückgibt, hätte das
Statement ein nicht leeres Ergebnis zurückliefern sollen. Sehen Sie in der
Beschreibung von @code{mysql_field_count()}-Funktion wegen eines Beispiels
nach.

Sie können durch Aufruf von @code{mysql_error()} oder @code{mysql_errno()}
auf einen Fehler überprüfen.

@cindex Anfragen, C-API-Ergebnisse


@node Query results, Getting unique ID, NULL mysql_store_result, C API problems
@c German node Anfrageergebnisse
@subsubsection Welche Ergebnisse kann ich von einer Anfrage bekommen?

Zusätzlich zur Ergebnismenge, die von einer Anfrage zurückgegeben wird,
können Sie auch folgende Informationen bekommen:

@itemize @bullet
@item
@code{mysql_affected_rows()} gibt die Anzahl von Zeilen zurück, die durch
die letzte Anfrage betroffen wurden, wenn Sie ein @code{INSERT},
@code{UPDATE} oder @code{DELETE} ausführen. Eine Ausnahme besteht darin,
wenn @code{DELETE} ohne eine @code{WHERE}-Klausel benutzt wird. In diesem
Fall wird die Tabelle leer neu erzeugt, was viel schneller ist! Daher gibt
@code{mysql_affected_rows()} 0 für die Anzahl betroffener Datensätze
zurück.

@item
@code{mysql_num_rows()} gibt die Anzahl von Zeilen in einer Ergebnismenge
zurück. Bei @code{mysql_store_result()} kann @code{mysql_num_rows()}
aufgerufen werden, sobald @code{mysql_store_result()} etwas zurückgibt. Bei
@code{mysql_use_result()} kann @code{mysql_num_rows()} erst aufgerufen
werden, nachdem Sie alle Zeilen mit @code{mysql_fetch_row()} geholt haben.

@item
@code{mysql_insert_id()} gibt die Kennung zurück, die von der letzten
Anfrage erzeugt wurde, die eine Zeile in eine Tabelle mit einem
@code{AUTO_INCREMENT}-Index einfügte. @xref{mysql_insert_id, ,
@code{mysql_insert_id()}}.

@item
Einige Anfragen (@code{LOAD DATA INFILE ...}, @code{INSERT INTO ... SELECT
...}, @code{UPDATE}) geben zusätzliche Informationen zurück. Das Ergebnis
wird von @code{mysql_info()} zurückgegeben. Siehe die Beschreibung für
@code{mysql_info()} hinsichtlich des Formats der Zeichenkette, die diese
Funktion zurückgibt. @code{mysql_info()} gibt einen @code{NULL}-Zeiger
zurück, wenn es keine zusätzlichen Informationen gibt.
@end itemize


@node Getting unique ID, C API linking problems, Query results, C API problems
@c German node Eindeutige Kennung erhalten
@subsubsection Wie erhalte ich die eindeutige Kennung für die letzte eingefügte Zeile?

@cindex eindeutige Kennung
@cindex letzte Zeile, eindeutige Kennung
@cindex Kennung, eindeutige
@cindex Tabellen, eindeutige Kennung für die letzte Zeile

Wenn Sie einen Datensatz in eine Tabelle einfügen, der eine Spalte enthält,
die das @code{AUTO_INCREMENT}-Attribut hat, erhalten Sie die letzte
erzeugte Kennung durch Aufruf der @code{mysql_insert_id()}-Funktion.

Sie können die Kennung auch dadurch abrufen, dass Sie die
@code{LAST_INSERT_ID()}-Funktion in einer Anfrage-Zeichenkette verwenden,
die Sie an @code{mysql_query()} übergeben.

Sie können überprüfen, ob ein @code{AUTO_INCREMENT}-Index benutzt wird,
wenn Sie folgenden Code ausführen. Er prüft auch, ob die Anfrage ein
@code{INSERT} mit einem @code{AUTO_INCREMENT}-Index war:

@example
if (mysql_error(&mysql)[0] == 0 &&
    mysql_num_fields(ergebnis) == 0 &&
    mysql_insert_id(&mysql) != 0)
@{
    used_id = mysql_insert_id(&mysql);
@}
@end example

Die letzte erzeugte Kennung wird im Server auf der Grundlage der jeweiligen
Verbindung gewartet. Sie wird nicht durch andere Clients geändert. Sie wird
nicht einmal geändert, wenn Sie eine andere @code{AUTO_INCREMENT}-Spalte
mit einem nicht magischen Wert aktualisieren (einem Wert, der nicht
@code{NULL} und nicht @code{0} ist).

Wenn Sie die Kennung benutzen wollen, die für eine Tabelle erzeugt wurde,
um sie in eine zweite Tabelle einzufügen, können Sie SQL-Statements wie
folgt benutzen:

@example
INSERT INTO foo (auto,text)
    VALUES(NULL,'text');              # Kennung durch Einfügen von NULL erzeugen
INSERT INTO foo2 (id,text)
    VALUES(LAST_INSERT_ID(),'text');  # Kennung in zweiter Tabelle benutzen
@end example


@node C API linking problems,  , Getting unique ID, C API problems
@c German node C-API-Linking-Probleme
@subsubsection Probleme beim Linken mit der C-API

@cindex Linken, Probleme
@cindex C-API, Link-Probleme

Wenn Sie mit der C-API linken, können auf manchen Systemen folgende Fehler
auftreten:

@example
gcc -g -o client test.o -L/usr/local/lib/mysql -lmysqlclient -lsocket -lnsl

Undefined        first referenced
 symbol          in file
floor            /usr/local/lib/mysql/libmysqlclient.a(password.o)
ld: fatal: Symbol referencing errors. No output written to client
@end example

Wenn das auf Ihrem System passiert, müssen Sie die math-Bibliothek
einschließen, indem Sie @code{-lm} am Ende der Kompilier- / Link-Zeile
hinzufügen.


@node Building clients, Threaded clients, C API problems, C
@c German node Clients bauen
@subsection Client-Programme bauen

@cindex Client-Programme, bauen
@cindex linken
@cindex bauen, Client-Programme
@cindex Programme, Client

Wenn Sie MySQL-Clients kompilieren, die Sie selbst geschrieben oder von
Dritten erhalten haben, müssen diese mit der @code{-lmysqlclient
-lz}-Option für den Link-Befehl gelinkt werden. Eventuell sollten Sie auch
eine @code{-L}-Option verwenden, um dem Linker mitzuteilen, wo sich die
Bibliothek befindet. Wenn zum Beispiel die Bibliothek in
@file{/usr/local/mysql/lib} installiert ist, benutzen Sie
@code{-L/usr/local/mysql/lib -lmysqlclient -lz} für den Link-Befehl.

Für Clients, die MySQL-Header-Dateien benutzen, müssen Sie eventuell eine
@code{-I}-Option angeben, wenn Sie sie kompilieren (zum Beispiel
@code{-I/usr/local/mysql/include}), so dass der Kompiler die Header-Dateien
finden kann.


@node Threaded clients, libmysqld, Building clients, C
@c German node Threaded Clients
@subsection Wie man einen threaded Client herstellt

@cindex Clients, Threaded
@cindex Threaded Clients

Die Client-Bibliothek ist fast Thread-sicher. Das größte Problem besteht
darin, dass die Subroutinen in @file{net.c}, die von Sockets lesen, nicht
Interrupt-sicher sind. Das wurde mit dem Hintergedanken gemacht, dass Sie
eventuell Ihre eigenen Alarme haben möchten, die ein langes Lesen vom
Server unterbrechen können. Wenn Sie Interrupt-Handler für den
@code{SIGPIPE}-Interrupt installieren, sollte die Socket-Handhabung
Thread-sicher sein.

In den älteren Binärdistributionen wurden die Client-Bibliotheken
normalerweise nicht mit der Thread-sicheren Option kompiliert (die
Windows-Binärdateien sind vorgabemäßig Thread-sicher kompiliert). Neuere
Binärdistributionen sollten sowohl eine normale als auch eine
Thread-sichere Client-Bibliothek haben.

Um einen threaded Client zu erhalten, bei dem Sie den Client durch andere
Threads unterbrechen (interrupt) und Zeitüberschreitungen (Timeouts) setzen
können, wenn Sie mit dem MySQL-Server kommunizieren, sollten Sie die
@code{-lmysys}-, @code{-lstring}-, und @code{-ldbug}-Bibliotheken und den
@code{net_serv.o}-Code benutzen, den der Server benutzt.

Wenn Sie keine Unterbrechungen (Interrupts) oder Zeitüberschreitungen
(Timeouts) benötigen, können Sie einfach eine Thread-sicher
Client-Bibliothek @code{(mysqlclient_r)} kompilieren und diese benutzen.
@xref{C,,MySQL-C-API}. In diesem Fall müssen Sie sich nicht um die
@code{net_serv.o}-Objektdatei oder die anderen MySQL-Bibliotheken kümmern.

Wenn Sie einen threaded Client benutzen und Unterbrechungen (Interrupts)
und Zeitüberschreitungen (Timeouts) benutzen wollen, können Sie in
umfangreicher Weise die Routinen in der @file{thr_alarm.c}-Datei benutzen.
Wenn Sie Routinen aus der @code{mysys}-Bibliothek benutzen, müssen Sie
lediglich daran denken, @code{my_init()} zuerst aufzurufen!
@xref{C Thread functions}.

Alle Funktionen ausser @code{mysql_real_connect()} sind vorgabemäßig
Thread-sicher. Die folgenden Hinweise beschreiben, wie man eine
Thread-sichere Client-Bibliothek kompiliert und sie auf Thread-sichere
Weise benutzt. (Die unten stehenden Hinweise für
@code{mysql_real_connect()} beziehen sich in der Tat auch auf
@code{mysql_connect()}. Weil aber @code{mysql_connect()} veraltet ist,
sollten Sie in jedem Fall @code{mysql_real_connect()} benutzen.)

Um @code{mysql_real_connect()} Thread-sicher zu machen, müssen Sie die
Client-Bibliothek mit diesem Befehl neu kompilieren:

@example
shell> ./configure --enable-thread-safe-client
@end example

Das erzeugt eine Thread-sichere Client-Bibliothek @code{libmysqlclient_r}.
@code{--enable-thread-safe-client}. Diese Bibliothek ist pro Verbindung
Thread-sicher. Sie können zwei Threads dieselbe Verbindung benutzen lassen,
solange Sie folgendes tun:

@itemize @bullet
@item
Zwei Threads können zur gleichen Zeit keine Anfrage an MySQL über dieselbe
Verbindung schicken. Insbesondere müssen Sie sicherstellen, dass zwischen
einem @code{mysql_query()} und einem @code{mysql_store_result()} kein
anderer Thread dieselbe Verbindung benutzt.
@item
Viele Threads können auf unterschiedliche Ergebnismengen zugreifen, die mit
@code{mysql_store_result()} abgerufen wurden.
@item
Wenn Sie @code{mysql_use_result} benutzen, müssen Sie sicherstellen, dass
kein anderer Thread irgend etwas über dieselbe Verbindung anfragt, bis die
Ergebnismenge geschlossen wurde. Für threaded Clients, die dieselbe
Verbindung benutzen, ist es jedoch am besten, @code{mysql_use_result()} zu
benutzen.
@item

Wenn Sie mehrfache Threads über dieselbe Verbindung benutzen wollen, müssen
Sie eine mutex-Sperre um Ihre @code{mysql_query()}- und
@code{mysql_store_result()}-Aufruf-Kombination haben. Sobald
@code{mysql_store_result()} fertig ist, kann die Sperre aufgehoben werden
und andere Threads können über dieselbe Verbindung anfragen.
@item
Wenn Sie mit POSIX-Threads programmieren, können Sie
@code{pthread_mutex_lock()} und @code{pthread_mutex_unlock()} benutzen, um
eine mutex-Sperre aufzubauen und aufzuheben.
@end itemize

Sie müssen folgendes wissen, wenn Sie einen Thread haben, der
MySQL-Funktionen aufruft, dieser Thread aber keine Verbindung zur
MySQL-Datenbank aufgebaut hat:

Wenn Sie @code{mysql_init()} oder @code{mysql_connect()} aufrufen, erzeugt
MySQL eine Thread-spezifische Variable für diesen Thread, die von der
Debug-Bibliothek benutzt wird (unter anderem).

Wenn Sie in einem Thread-Aufruf eine MySQL-Funktion haben, bevor ein Thread
@code{mysql_init()} oder @code{mysql_connect()} aufgerufen hat, hat der
Thread nicht notwendigerweise Thread-spezifische Variablen zur Hand, und
Sie werden wahrscheinlich früher oder später einen Coredump erhalten.
 
Damit alles reibungslos funktioniert, müssen Sie folgendes tun:

@enumerate
@item
Rufen Sie bei Programmbeginn @code{my_init()} auf, wenn Ihr Programm
irgend welche MySQL-Funktion vor dem Aufruf von @code{mysql_real_connect()}
benutzt.
@item
Rufen Sie @code{mysql_thread_init()} im Thread-Handler auf, bevor Sie
irgend welche MySQL-Funktionen aufrufen.
@item
Rufen Sie im Thread @code{mysql_thread_end()} auf, bevor Sie
@code{pthread_exit()} aufrufen. Das gibt Speicher frei, der von
MySQL-Thread-spezifischen Variablen benutzt wird.
@end enumerate

Eventuell erhalten Sie Fehler wegen undefinierter Symbole, wenn Sie Ihren
Client mit @code{mysqlclient_r} linken. In den meisten Fällen liegt das
daran, dass Sie die Thread-Bibliotheken nicht auf der Link- /
Kompilierzeile eingeschlossen haben.

@node libmysqld,  , Threaded clients, C
@c German node libmysqld
@subsection libmysqld, die eingebettete MySQL-Server-Bibliothek

@cindex libmysqld
@cindex eingebettete MySQL-Server-Bibliothek


@menu
* libmysqld overview::          
* libmysqld compiling::         
* libmysqld example::           
* libmysqld licensing::         
@end menu

@node libmysqld overview, libmysqld compiling, libmysqld, libmysqld
@c German node libmysqld Überblick
@subsubsection Überblick über die eingebettete MySQL-Server-Bibliothek

Die eingebettete MySQL-Server-Bibliothek ermöglicht es, einen MySQL-Server
mit allen Features innerhalb einer Client-Applikation laufen zu lassen. Die
hauptsächlichen Vorteile sind erhöhte Geschwindigkeit und einfachere
Verwaltung eingebetteter Applikationen.

@node libmysqld compiling, libmysqld example, libmysqld overview, libmysqld
@c German node libmysqld kompilieren
@subsubsection Programme mit @code{libmysqld} kompilieren

Momentan müssen alle unterstützten Bibliotheken explizit aufgelistet
werden, wenn Sie mit @code{-lmysqld} linken. In Zukunft wird
@code{mysql_config --libmysqld-libs} die Bibliotheken benennen, um das zu
erleichtern. Darüber hinaus werden alle unterstützten Bibliotheken
wahrscheinlich in libmysqld eingeschlossen werden, um dies noch weiter zu
vereinfachen.

Die korrekten Flags zum Kompilieren und Linken eines threaded Programms
müssen benutzt werden, selbst wenn Sie nicht direkt irgend welche
Thread-Funktionen in Ihrem Code aufrufen.

@node libmysqld example, libmysqld licensing, libmysqld compiling, libmysqld
@c German node libmysqld Beispiel
@subsubsection Ein einfaches Embedded-Server-Beispiel

Dieses Beispiel-Programm und makefile sollten ohne Änderungen auf einem
Linux- oder FreeBSD-System funktionieren. Bei anderen Betriebssystemen sind
kleinere Änderungen notwendig. Dieses Beispiel ist so angelegt, dass
genügend Details dargestellt werden, um die Problematik zu verstehen, ohne
zu viel "Verwirrendes" einzubringen, das Teil einer echten Applikation ist.

Um das Beispiel auszuprobieren, erzeugen Sie ein @file{example}-Verzeichnis
auf derselben Ebene wie das mysql-4.0-Quell-Verzeichnis. Speichern Sie die
@file{example.c}-Quelle und das @file{GNUmakefile} im Verzeichnis und
lassen Sie GNU-@file{make} innerhalb des @file{example}-Verzeichnisses
laufen.

@file{example.c}
@example
/*
 * Ein einfacher Beispiel-Client, der die eingebettete
 * MySQL-Server-Bibliothek benutzt
 */

#include <mysql.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

enum on_error @{ E_okay, E_warn, E_fail @};

static void   die(MYSQL *db, char *fmt, ...);
MYSQL *db_connect(const char *dbname);
void db_disconnect(MYSQL *db);
void db_do_Anfrage(MYSQL *db, const char *query, enum on_error on_error);

const char *server_groups[] = @{ "test_client_SERVER", "server", NULL @};

int
main(int argc, char **argv)
@{
  MYSQL *one, *two;

  /* Das muss vor allen weiteren mysql-Funktionen aufgerufen werden.
   *
   * Sie können mysql_server_init(0, NULL, NULL) benutzen, 
   * was den Server initialisiert und die Gruppen
   * groups = @{ "server", NULL @} benutzt.
   *
   * In Ihre $HOME/.my.cnf-Datei sollten Sie folgendes eintragen:

[test_client_SERVER]
language = /pfad/zur/quelle/von/mysql/sql/share/english

   * Natürlich können Sie auch argc und argv ändern,
   * bevor Sie sie an diese Funktion übergeben.
   * Oder erzeugen Sie neue auf jede Art, die Sie wollen.
   * Alle Argumente in argv (ausser argv[0], was der Programmname ist)
   * müssen allerdings gültige Optionen für den MySQL-Server sein.
   * Wenn Sie diesen Client gegen die normale mysqlclient-
   * Bibliothek linken, ist diese Funktion nur ein Stumpf, der nichts tut.
   */
  mysql_server_init(argc, argv, server_groups);

  one = db_connect("test");
  two = db_connect(NULL);

  db_do_query(one, "show table status", E_fail);
  db_do_query(two, "show databases", E_fail);

  mysql_close(two);
  mysql_close(one);

  /* Folgendes muss nach allen anderen mysql-Funktionen aufgerufen werden */
  mysql_server_end();

  exit(EXIT_SUCCESS);
@}

void
die(MYSQL *db, char *fmt, ...)
@{
  va_list ap;
  va_start(ap, fmt);
  vfprintf(stderr, fmt, ap);
  va_end(ap);
  putc('\n', stderr);
  if (db)
    db_disconnect(db);
  exit(EXIT_FAILURE);
@}

MYSQL *
db_connect(const char *dbname)
@{
  MYSQL *db = mysql_init(NULL);
  if (!db)
    die(db, "mysql_init fehlgeschlagen: kein Speicher mehr");
  mysql_options(db, MYSQL_READ_DEFAULT_GROUP, "simple");
  if (!mysql_real_connect(db, NULL, NULL, NULL, dbname, 0, NULL, 0))
    die(db, "mysql_real_connect fehlgeschlagen: %s", mysql_error(db));

  return db;
@}

void
db_disconnect(MYSQL *db)
@{
  mysql_close(db);
@}

/*
 * show_query: Dieser Code ist aus mysql.cc. Diese Funktion
 * ist dafür gedacht, intern für db_do_query() benutzt zu werden.
 */
static char *
show_query(MYSQL *db)
@{
  MYSQL_RES   *res;
  MYSQL_FIELD *field;
  MYSQL_ROW    row;
  char         sep[256], *psep = sep;
  char        *is_num = 0;
  char        *err = 0;
  unsigned int length = 1;      /* anfangs "|" */
  unsigned int off;

  if (!(res = mysql_store_result(db)))
    return mysql_error(db);

  if (!(is_num = malloc(mysql_num_fields(res))))
  @{
    err = "Kein Speicher mehr";
    goto err;
  @}

  /* set up */
  *psep++ = '+';
  while ((field = mysql_fetch_field(res)))
  @{
    unsigned int len = strlen(field->name);
    if (len < field->max_length)
      len = field->max_length;
    if (len < 2 && !IS_NOT_NULL(field->flags))
      len = 2;  /* \N */
    field->max_length = len + 1;        /* die API verbiegen ... */
    len += 2; length += len + 1;        /* " " davor, " |" danach */
    if (length >= 255)
    @{
      err = "Zeile zu lang";
      goto err;
    @}
    memset(psep, '-', len); psep += len;
    *psep++ = '+';
    *psep   = '\0';
  @}

  /* Spaltenüberschriften */
  puts(sep);
  mysql_field_seek(res,0);
  fputc('|',stdout);
  für (off=0; (field = mysql_fetch_field(res)) ; off++)
  @{
    printf(" %-*s|",field->max_length, field->name);
    is_num[off]= IS_NUM(field->type);
  @}
  fputc('\n',stdout);
  puts(sep);

  /* Zeilen */
  while ((row = mysql_fetch_row(res)))
  @{
    (void) fputs("|",stdout);
    mysql_field_seek(res,0);
    for (off=0 ; off < mysql_num_fields(res); off++)
    @{
      field = mysql_fetch_field(res);
      printf(is_num[off] ? "%*s |" : " %-*s|",
             field->max_length, row[off] ? (char*) row[off] : "NULL");
    @}
    (void) fputc('\n',stdout);
  @}
  puts(sep);

err:
  if (is_num)
    free(is_num);
  mysql_free_result(res);

  return err;
@}

void
db_do_query(MYSQL *db, const char *query, enum on_error on_error)
@{
  char *err = 0;
  if (mysql_query(db, query) != 0)
    goto err;

  if (mysql_field_count(db) > 0)
  @{
    if ((err = show_query(db)))
      goto err;
  @}
  else if (mysql_affected_rows(db))
    printf("Betroffene Zeilen: %lld [%s]\n", mysql_affected_rows(db), query);

  return;

err:
  switch (on_error) @{
  case E_okay:
    break;
  case E_warn:
    fprintf(stderr, "db_do_query fehlgeschlagen: %s [%s]\n",
        err ? err : mysql_error(db), query);
    break;
  case E_fail:
    die(db, "db_do_query fehlgeschlagen: %s [%s]",
        err ? err : mysql_error(db), query);
    break;
  @}
@}
@end example

@file{GNUmakefile}
@example
# Platzieren Sie diese in Ihr mysql-Quell-Verzeichnis
m        := ../mysql-4.0

CC       := cc
CPPFLAGS := -I$m/include -D_thread_SAFE -D_REENTRANT
CFLAGS   := -g -W -Wall
LDFLAGS  := -static
LDLIBS    = $(embed_libs) -lz -lm -lcrypt

ifneq (,$(shell grep FreeBSD /COPYRIGHT 2>/dev/null))
# FreeBSD
LDFLAGS += -pThread
else
# Linux wird angenommen
LDLIBS += -lpThread
endif


# Standard-Bibliotheken

embed_libs := \
        $m/libmysqld/.libs/libmysqld.a \
        $m/isam/libnisam.a \
        $m/myisam/libmyisam.a \
        $m/heap/libheap.a \
        $m/merge/libmerge.a \
        $m/myisammrg/libmyisammrg.a


# Optional gebaute Bibliotheken

ifneq (,$(shell test -r $m/innobase/usr/libusr.a && echo "yes"))
embed_libs += \
        $m/innobase/usr/libusr.a \
        $m/innobase/odbc/libodbc.a \
        $m/innobase/srv/libsrv.a \
        $m/innobase/que/libque.a \
        $m/innobase/srv/libsrv.a \
        $m/innobase/dict/libdict.a \
        $m/innobase/ibuf/libibuf.a \
        $m/innobase/row/librow.a \
        $m/innobase/pars/libpars.a \
        $m/innobase/btr/libbtr.a \
        $m/innobase/trx/libtrx.a \
        $m/innobase/read/libread.a \
        $m/innobase/usr/libusr.a \
        $m/innobase/buf/libbuf.a \
        $m/innobase/ibuf/libibuf.a \
        $m/innobase/eval/libeval.a \
        $m/innobase/log/liblog.a \
        $m/innobase/fsp/libfsp.a \
        $m/innobase/fut/libfut.a \
        $m/innobase/fil/libfil.a \
        $m/innobase/lock/liblock.a \
        $m/innobase/mtr/libmtr.a \
        $m/innobase/page/libpage.a \
        $m/innobase/rem/librem.a \
        $m/innobase/thr/libthr.a \
        $m/innobase/com/libcom.a \
        $m/innobase/sync/libsync.a \
        $m/innobase/data/libdata.a \
        $m/innobase/mach/libmach.a \
        $m/innobase/ha/libha.a \
        $m/innobase/dyn/libdyn.a \
        $m/innobase/mem/libmem.a \
        $m/innobase/sync/libsync.a \
        $m/innobase/ut/libut.a \
        $m/innobase/os/libos.a \
        $m/innobase/ut/libut.a
endif

ifneq (,$(shell test -r $m/bdb/build_unix/libdb.a && echo "yes"))
embed_libs += $m/bdb/build_unix/libdb.a
endif


# Unterstützte Bibliotheken

embed_libs += \
        $m/mysys/libmysys.a \
        $m/strings/libmystrings.a \
        $m/dbug/libdbug.a \
        $m/regex/libregex.a


# Optional gebaute unterstützte Bibliotheken

ifneq (,$(shell test -r $m/readline/libreadline.a && echo "yes"))
embed_libs += $m/readline/libreadline.a
endif

# Das funktioniert bei einfachen Ein-Datei-Test-Programmen
sources := $(wildcard *.c)
objects := $(patsubst %c,%o,$(sources))
targets := $(basename $(sources))

all: $(targets)

clean:
	rm -f $(targets) $(objects) *.core
@end example

@node libmysqld licensing,  , libmysqld example, libmysqld
@c German node libmysqld Lizensierung
@subsubsection Lizensierung des eingebetteten Servers

Der MySQL-Quelltext wird von der GNU-GPL-Lizenz abgedeckt
(@pxref{GPL license}). Eine Folge davon ist, dass jegliches Programm, das
durch Linken mit @code{libmysqld} den MySQL-Quelltext enthält, als freie
Software (unter einer mit der GPL kompatiblen Lizenz) veröffentlicht werden
muss.

Wir ermutigen jeden, freie Software durch Veröffentlichung von Code unter
der GPL oder einer kompatiblen Lizenz zu fördern. Für diejenigen, die dazu
nicht in der Lage sind, ist eine weitere Option, den MySQL-Code von MySQL
AB unter einer lockereren Lizenz zu erwerben. Wegen Details betreffs dieses
Themas siehe unter @ref{Lizenzpolitik}.

@node Cplusplus, Java, C, Clients
@c German node Cplusplus
@section MySQL-C++-APIs



@cindex C++-APIs

Zwei APIs sind im
MySQL-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib-Verzeichnis}
verfügbar.


@menu
* Borland C++::                 
@end menu

@node Borland C++,  , Cplusplus, Cplusplus
@c German node Borland C++
@subsection Borland C++

@cindex Borland C++-Kompiler

Sie können den MySQL-Windows-Quellcode mit Borlund C++ 5.02 kompilieren.
(Der Windows-Quellcode beinhaltet nur Projekte für Microsoft VC++, für
Borland C++ müssen Sie die Projektdateien selbst erstellen).

Ein bekanntes Problem bei Borland C++ ist, dass es eine andere
Strukturanordnung benutzt als VC++. Das bedeutet, dass Sie Probleme
bekommen, wenn Sie versuchen, die vorgabemäßigen
@code{libmysql.dll}-Bibliotheken (die mit VC++ kompiliert wurden) mit
Borland C++ zu verwenden. Sie können eins der folgenden Dinge tun, um
dieses Problem zu vermeiden:

@itemize @bullet
@item
Sie können statische MySQL-Bibliotheken für Borland C++ verwenden, die Sie
unter @uref{http://www.mysql.com/downloads/os-win32.html} finden.
@item
Rufen Sie @code{mysql_init()} nur mit @code{NULL} als Argument auf, kein
vorher zugewiesenes (prä-alloziertes) MySQL-Strukt.
@end itemize


@node Java, Python, Cplusplus, Clients
@c German node Java
@section MySQL Java Connectivity (JDBC)

@cindex Java-Connectivity
@cindex JDBC

Es gibt 2 unterstützte JDBC-Treiber für MySQL (den mm-Treiber und den
Reisin JDBC-Treiber). Sie finden den mm-Treiber unter
@uref{http://mmmysql.sourceforge.net/} oder
@uref{http://www.mysql.com/Downloads/Contrib/} und den Reisin-Treiber unter
@uref{http://www.caucho.com/Projekte/jdbc-mysql/index.xtp}. Wegen der
Dokumentation sehen Sie sich irgend eine JDBC-Dokumentation durch sowie die
eigene Dokumentation der Treiber wegen MySQL-spezifischer Features.


@node Python, Tcl, Java, Clients
@c German node Python
@section MySQL-Python-APIs

@cindex Python-APIs

Das
MySQL-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib-Verzeichnis}
enthält eine Python-Schnittstelle, die von Joseph Skinner geschrieben
wurde.

Sie können auch die Python-Schnittstelle zu iODBC benutzen, um auf einen
MySQL-Server zuzugreifen.
@uref{http://starship.skyport.net/~lemburg/,mxODBC}


@node Tcl, Eiffel, Python, Clients
@c German node Tcl
@section MySQL-Tcl-APIs

@cindex Tcl-APIs

@uref{http://www.binevolve.com/~tdarugar/tcl-sql/, Tcl bei binevolve}.
Das
@uref{http://www.mysql.com/Downloads/Contrib,Contrib-Verzeichnis} enthält
eine Tcl-Schnittstelle, die auf msqltcl 1.50 basiert.


@node Eiffel,  , Tcl, Clients
@c German node Eiffel
@section MySQL-Eiffel-Wrapper

@cindex Eiffel-Wrapper
@cindex Wrapper, Eiffel

Das
MySQL-@uref{http://www.mysql.com/Downloads/Contrib/,Contrib-Verzeichnis}
enthält einen Eiffel-Wrapper, der von Michael Ravits geschrieben wurde.


@node Extending MySQL, Problems, Clients, Top
@c German node MySQL erweitern
@chapter MySQL erweitern



@menu
* MySQL internals::             
* Adding procedures::           
* MySQL-Interna::               
@end menu

@node MySQL internals, Adding procedures, Extending MySQL, Extending MySQL
@c German node Hinzufügen von Funktionen
@section Hinzufügen neuer Funktionen zu MySQL

@cindex Funktionen, neue
@cindex hinzufügen, neue Funktionen
@cindex benutzerdefinierte Funktionen, hinzufügen
@cindex UDFs, Definition
@cindex Funktionen, benutzerdefinierte

Es gibt zwei Möglichkeiten, MySQL neue Funktionen hinzuzufügen:

@itemize @bullet
@item
Sie können die Funktion über die benutzerdefinierbare Funktions-
(UDF-) Schnittstelle hinzufügen. Benutzerdefinierbare Funktionen werden
dynamisch mittels @code{CREATE FUNCTION} und @code{DROP
FUNCTION}-Statements hinzugefügt bzw. gelöscht.
@xref{CREATE FUNCTION, ,@code{CREATE FUNCTION}}.

@item
Sie können die Funktion als native (eingebaute) MySQL-Funktion hinzufügen.
Native Funktionen werden in den @code{mysqld}-Server kompiliert und stehen
dann dauerhaft zur Verfügung.
@end itemize

Jede Methode hat Vorteile und Nachteile:

@itemize @bullet
@item
Wenn Sie eine benutzerdefinierte Funktion schreiben, müssen Sie die
Objekt-Datei zusätzlich zum Server selbst installieren. Wenn Sie Ihre
Funktion in den Server einkompilieren, brauchen Sie das nicht zu tun.
@item
Sie können der binären MySQL-Distribution benutzerdefinierte Funktionen
hinzufügen. Native Funktionen erfordern, dass Sie eine Quelldistribution
verändern.
@item
Wenn Sie Ihre MySQL-Distribution aktualisieren, können Sie weiterhin Ihre
vorher installierten benutzerdefinierten Funktionen benutzen. Bei nativen
Funktionen müssen Sie Ihre Änderungen jedes Mal wiederholen, wenn Sie
aktualisieren.
@end itemize

Gleich welche Methode Sie zum Hinzufügen neuer Funktionen verwenden, können
Sie diese genau wie die nativen Funktionen, z. B. @code{ABS()} oder
@code{SOUNDEX()}, benutzen.



@menu
* CREATE FUNCTION::             
* Adding UDF::                  
* Adding native function::      
@end menu

@node CREATE FUNCTION, Adding UDF, MySQL internals, MySQL internals
@c German node CREATE FUNCTION
@subsection @code{CREATE FUNCTION / DROP FUNCTION}-Syntax

@findex CREATE FUNCTION
@findex DROP FUNCTION
@findex UDF-Funktionen
@findex benutzerdefinierte Funktionen
@findex Funktionen, benutzerdefinierte

@example
CREATE [AGGREGATE] FUNCTION funktion RETURNS @{STRING|REAL|INTEGER@}
       SONAME gemeinsame_bibliothek

DROP FUNCTION funktion
@end example

Eine benutzerdefinierte Funktion (UDF) ist eine Möglichkeit, MySQL durch
eine neue Funktion zu erweitern, die wie die nativen (eingebauten)
MySQL-Funktionen, z. B. @code{ABS()} und @code{CONCAT()}, funktioniert.

@code{AGGREGATE} ist eine neue Option für MySQL-Version 3.23. Eine
@code{AGGREGATE}-Funktion funktioniert genau wie eine native MySQL-
@code{GROUP}-Funktion wie @code{SUM} oder @code{COUNT()}.

@code{CREATE FUNCTION} speichert den Funktionnamen, -typ und die gemeinsam
genutzte Bibliothek in der @code{mysql.func}-Systemtabelle. Sie benötigen
die @strong{insert}- und @strong{delete}-Berechtigungen für die
@code{mysql}-Datenbank, um Funktionen zu erzeugen und zu löschen.

Alle aktiven Funktionen werden jedes Mal wieder geladen, wenn der Server
startet, es sei denn, Sie starten ihn mit der
@code{--skip-grant-tables}-Option. In diesem Fall wird die
UDF-Initialisierung übersprungen, so dass UDFs nicht verfügbar sind. (Eine
aktive Funktion ist eine, die mit @code{CREATE FUNCTION} geladen und nicht
mit @code{DROP FUNCTION} entfernt wurde.)

Wegen weiterer Anleitungen zum Schreiben benutzerdefinierte Funktionen
siehe @ref{MySQL internals}. Damit der UDF-Mechanismus
funktioniert, müssen Funktionen in C oder C++ geschrieben sein. Ihr
Betriebssystem muss dynamisches Laden unterstützen und Sie müssen
@code{mysqld} dynamisch (nicht statisch) kompiliert haben.

Beachten Sie, dass Sie für das Funktionieren von @code{AGGREGATE} eine
@code{mysql.func}-Tabelle benötigen, die die Spalte @code{typ} enthält.
Wenn das nicht der Fall ist, sollten Sie das Skript
@code{mysql_fix_privilege_tables} laufen lassen, um diesen Mangel zu
beheben.


@node Adding UDF, Adding native function, CREATE FUNCTION, MySQL internals
@c German node UDF hinzufügen
@subsection Hinzufügen einer neuen benutzerdefinierten Funktion

@cindex hinzufügen, benutzerdefinierte Funktionen
@cindex benutzerdefinierte Funktionen, hinzufügen
@cindex Funktionen, benutzerdefinierte, hinzufügen



Damit der UDF-Mechanismus funktioniert, müssen Funktionen in C oder C++
geschrieben sein. Ihr Betriebssystem muss dynamisches Laden unterstützen
und Sie müssen @code{mysqld} dynamisch (nicht statisch) kompiliert
haben. Die MySQL-Quelldistribution enthält eine Datei
@file{sql/udf_example.cc}, die 5 neue Funktionen definiert. Sehen Sie in
dieser Datei nach, wie die UDF-Aufruf-Konventionen funktionieren.

Damit @code{mysqld} UDF-Funktionen benutzen kann, sollten Sie MySQL mit
@code{--with-mysqld-ldflags=-rdynamic} konfigurieren. Der Grund liegt
darin, dass Sie auf vielen Plattformen (inklusive Linux) eine dynamische
Bibliothek (mit @code{dlopen()}) von einem statisch gelinkten Programm
laden können, was Sie erhalten würden, wenn Sie
@code{--with-mysqld-ldflags=-all-static} benutzen. Wenn Sie eine UDF
benutzen wollen, die auf Symbole von @code{mysqld} zugreifen muss (wie das
@code{methaPhone}-Beispiel in @file{sql/udf_example.cc}, das
@code{default_charset_info} benutzt), müssen Sie das Programm mit
@code{-rdynamic} benutzen (siehe @code{man dlopen}).

Für jede Funktion, die Sie in SQL-Statements benutzen wollen, sollten Sie
die entsprechenden C- (oder C++-) Funktionen benutzen. In den unten
stehenden Ausführungen wird ``xxx'' als Beispiel-Funktionsname benutzt. Um
zwischen SQL- und C-/C++-Benutzung zu unterscheiden, kennzeichnet
@code{XXX()} (Großschreibung) einen SQL-Funktionsaufruf und @code{xxx()}
(Kleinschreibung) einen C-/C++-Funktionsaufruf.

The C-/C++-Funktionen, die Sie für die Implementierung der Schnittstelle
für @code{XXX()} schreiben, sind:

@table @asis
@item @code{xxx()} (required)
Die Hauptfunktion. Hier wird das Funktionsergebnis berechnet. Der
Zusammenhang zwischen dem SQL-Typ und dem Rückgabe-Typ Ihrer
C-/C++-Funktion ist unten dargestellt:

@multitable @columnfractions .2 .8
@item @strong{SQL-Typ} @tab @strong{C-/C++-Typ}
@item @code{STRING}     @tab @code{char *}
@item @code{INTEGER}    @tab @code{long long}
@item @code{REAL}       @tab @code{double}
@end multitable

@item @code{xxx_init()} (optional)
Die Initialisierungsfunktion für @code{xxx()}. Sie kann für folgendes
benutzt werden:

@itemize @bullet
@item
Um die Anzahl von Argumenten für @code{XXX()} zu prüfen.
@item
Um zu prüfen, ob die Argumente vom erforderlichen Typ sind oder,
alternativ, MySQL mitzuteilen, den Argumenttyp zu erzwingen, den Sie beim
Aufruf der Hauptfunktion brauchen.
@item
Um jeglichen Speicher zuzuweisen, der von der Hauptfunktion benötigt wird.
@item
Um die maximale Länge des Ergebnisses anzugeben.
@item
Um (für @code{REAL}-Funktionen) die maximale Anzahl von Dezimalstellen
anzugeben.
@item
Um festzulegen, ob das Ergebnis @code{NULL} sein darf oder nicht.
@end itemize

@item @code{xxx_deinit()} (optional)
Die Deinitialisierungsfunktion für @code{xxx()}. Sie sollte jeglichen
Speicher freigeben (deallozieren), der durch die Initialisierungsfunktion
zugewiesen wurde.
@end table

Wenn ein SQL-Statement @code{XXX()} aufruft, ruft MySQL die
Initialisierungsfunktion @code{xxx_init()} auf, damit diese die notwendige
Einrichtung vornehmen kann wie Argumente prüfen oder Speicherzuweisung.
Wenn @code{xxx_init()} einen Fehler zurückgibt, wird das SQL-Statement mit
einer Fehlermeldung abgebrochen, die Haupt- und
Deinitialisierungsfunktionen werden nicht aufgerufen. Ansonsten wird die
Hauptfunktion @code{xxx()} für jede Zeile aufgerufen. Nachdem alle Zeilen
abgearbeitet sind, wird die Deinitialisierungsfunktion @code{xxx_deinit()}
aufgerufen, damit sie die erforderlichen Aufräumarbeiten ausführen kann.

Alle Funktionen müssen Thread-sicher sein (nicht nur die Hauptfunktion,
sondern auch die Initialisierungs- und Deinitialisierungsfunktionen). Das
heißt, dass Sie keinerlei globale oder statische Variablen zuweisen
dürfen, die sich ändern! Wenn Sie Speicher brauchen, sollten Sie ihn in
@code{xxx_init()} zuweisen und in @code{xxx_deinit()} freigeben.


@menu
* UDF calling::                 
* UDF arguments::               
* UDF return values::           
* UDF compiling::               
@end menu

@node UDF calling, UDF arguments, Adding UDF, Adding UDF
@c German node UDF-Aufruf-Sequenzen
@subsubsection UDF-Aufruf-Sequenzen

@cindex Sequenzen aufrufen, UDF

Die Hauptfunktion sollte wie unten dargestellt deklariert werden. Beachten
Sie, dass sich der Rückgabetyp und der Parameter unterscheiden, abhängig
davon, wie Sie die SQL-Funktion @code{XXX()} deklarieren, damit sie
@code{STRING}, @code{INTEGER} oder @code{REAL} im @code{CREATE
FUNCTION}-Statement zurückgibt:

@noindent
Bei @code{STRING}-Funktionen:

@example
char *xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *result, unsigned long *length,
              char *is_null, char *error);
@end example

@noindent
Bei @code{INTEGER}-Funktionen:

@example
long long xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
@end example

@noindent
Bei @code{REAL}-Funktionen:

@example
double xxx(UDF_INIT *initid, UDF_ARGS *args,
              char *is_null, char *error);
@end example

Die Initialisierungs- und Deinitialisierungsfunktionen werden wie folgt
deklariert:

@example
my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message);

void xxx_deinit(UDF_INIT *initid);
@end example

Der @code{initid}-Parameter wird an alle drei Funktionen übergeben. Er
zeigt auf eine @code{UDF_INIT}-Struktur, die benutzt wird, um Informationen
zwischen den Funktionen zu übermitteln. Die
@code{UDF_INIT}-Strukturmitglieder sind unten aufgelistet. Die
Initialisierungsfunktion sollte alle Mitglieder ausfüllen, die sie ändern
will. (Um für ein Mitglied den Vorgabewert zu verwenden, lassen Sie es
unverändert.)

@table @code
@item my_bool maybe_null
@code{xxx_init()} sollte @code{maybe_null} auf @code{1} setzen, wenn
@code{xxx()} @code{NULL} zurückgeben kann. Der Vorgabewert ist @code{1},
wenn irgend eins der Argumente als @code{maybe_null} deklariert ist.

@item unsigned int Dezimalstellen
Anzahl von Dezimalstellen. Der Vorgabewert ist die maximale Anzahl von
Dezimalstellen in den Argumenten, die an die Hauptfunktion übergeben
werden. (Wenn der Funktion beispielsweise die Argumente @code{1.34},
@code{1.345} und @code{1.3} übergeben werden, wäre der Vorgabewert 3, weil
@code{1.345} 3 Dezimalstellen hat.

@item unsigned int max_length
Die maximale Länge des Zeichenkettenergebnisses. Der Vorgabewert ist
unterschiedlich, abhängig vom Ergebnistyp der Funktion. Bei
Zeichenketten-Funktionen ist die Vorgabe die Länge des längsten Arguments.
Bei Ganzzahl-Funktionen ist die Vorgabe 21 Ziffern. Bei REAL-Funktionen ist
die Vorgabe 13 plus die Anzahl von Dezimalstellen, die von
@code{initid->Dezimalstellen} angezeigt werden. (Bei numerischen Funktionen
enthält die Länge jedes Vorzeichen- oder Dezimalpunkt-Zeichen.)

Wenn Sie einen Blob zurückgeben wollen, können Sie diesen auf 65 KB oder
16MB setzen. Der Speicher wird nicht zugewiesen, aber dazu verwendet, um zu
entscheiden, welcher Spaltentyp benutzt werden soll, falls es notwendig
werden sollte, Daten temporär zu speichern.

@item char *ptr
Ein Zeiger, den die Funktion für eigene Zwecke verwenden kann.
Beispielsweise können Funktionen @code{initid->ptr} benutzen, um
Informationen über den zugewiesenen Speicher zwischen den Funktionen zu
kommunizieren. Beispiel, um in @code{xxx_init()} Speicher zuzuweisen und
ihn diesem Zeiger zuzuordnen:

@example
initid->ptr = allocated_memory;
@end example

In @code{xxx()} und @code{xxx_deinit()} verweisen Sie auf
@code{initid->ptr}, um Speicher zu verwenden oder freizugeben.
@end table


@node UDF arguments, UDF return values, UDF calling, Adding UDF
@c German node UDF-Argumente
@subsubsection Verarbeitung von Argumenten

@cindex Verarbeitung von Argumenten
@cindex Verarbeitung, Argumente

Der @code{args}-Parameter zeigt auf eine @code{UDF_ARGS}-Struktur, die
unten aufgelistete Mitglieder hat:

@table @code
@item unsigned int arg_count
Die Anzahl von Argumenten. Prüfen Sie diesen Wert in der
Initialisierungsfunktion, wenn Sie wollen, dass Ihre Funktion mit einer
bestimmten Anzahl von Argumenten aufgerufen wird. Beispiel:

@example
if (args->arg_count != 2)
@{
    strcpy(message,"XXX() benoetigt zwei Argumente");
    return 1;
@}
@end example


@item enum Item_result *arg_type
Die Typen für jedes Argument. Die möglichen Typenwerte sind
@code{STRING_RESULT}, @code{INT_RESULT} und @code{REAL_RESULT}.

Um sicherzustellen, dass die Argumente vom angegebenen Typ sind und einen
Fehler zurückgeben, falls nicht, prüfen Sie das @code{arg_type}-Array in
der Initialisierungsfunktion. Beispiel:

@example
if (args->arg_type[0] != STRING_RESULT ||
    args->arg_type[1] != INT_RESULT)
@{
    strcpy(message,"XXX() erfordert eine Zeichenkette und eine Ganzzahl");
    return 1;
@}
@end example

Als Alternative dazu, dass Ihre Funktionsargumente von bestimmten Typen
sein müssen, können Sie die Initialisierungsfunktion benutzen, um die
@code{arg_type}-Elemente auf die Typen zu setzen, die Sie wollen. Das
veranlasst MySQL, die Typen der Argumente bei jedem Aufruf von @code{xxx()}
zu erzwingen. Um beispielsweise zu erzwingen, dass die ersten zwei
Argumente Zeichenkette und Ganzzahl sind, geben Sie in @code{xxx_init()}
folgendes ein:

@example
args->arg_type[0] = STRING_RESULT;
args->arg_type[1] = INT_RESULT;
@end example

@item char **args
@code{args->args} kommuniziert der Initialisierungsfunktion Informationen
über die allgemeine Natur der Argumente, mit der Ihre Funktion aufgerufen
wurde. Bei einem Konstanten-Argument @code{i} zeigt @code{args->args[i]}
auf den Argumentwert. (Siehe unten wegen Anleitungen, wie auf diesen Wert
korrekt zugegriffen wird.) Bei einem Nicht-Konstanten-Argument ist
@code{args->args[i]} @code{0}. Ein Konstanten-Argument ist ein Ausdruck,
der nur Konstanten wie @code{3} oder @code{4*7-2} oder @code{SIN(3.14)}
benutzt. Ein Nicht-Konstanten-Argument ist ein Ausdruck, der auf Werte
verweist, die sich von Zeile zu Zeile ändern können, wie Spaltennamen oder
Funktionen, die mit Nicht-Konstanten-Argumenten aufgerufen werden.

Bei jedem Aufruf der Hauptfunktion enthält @code{args->args} die
tatsächlichen Argumente, die für die Zeile übergeben werden, die momentan
verarbeitet wird.

Funktionen können auf ein Argument @code{i} wie folgt verweisen:

@itemize @bullet
@item
Ein Argument des Typs @code{STRING_RESULT} wird als ein Zeichenkettenzeiger
plus einer Länge angegeben, um die Handhabung von Binärdaten oder Daten
beliebiger Länge zu erlauben. Die Zeichenketten-Inhalte sind als
@code{args->args[i]} und die Zeichenkettenlänge als @code{args->lengths[i]}
verfügbar. Sie sollten nicht davon ausgehen, dass Zeichenketten
null-terminiert sind.

@item
Bei einem Argument des Typs @code{INT_RESULT} müssen Sie
@code{args->args[i]} zu einem @code{long long}-Wert machen (cast):

@example
long long int_val;
int_val = *((long long*) args->args[i]);
@end example

@item
Bei einem Argument des Typs @code{REAL_RESULT} müssen Sie
@code{args->args[i]} zu einem @code{double}-Wert machen (cast):

@example
double    real_val;
real_val = *((double*) args->args[i]);
@end example
@end itemize

@item unsigned long *lengths
Bei der Initialisierungsfunktion gibt das @code{lengths}-Array die maximale
Zeichenkettenlänge jedes Arguments an. Bei jedem Aufruf der Hauptfunktion
enthält @code{lengths} die tatsächlichen Längen jeglicher
Zeichenketten-Argumente, die für die momentan verarbeitete Zeile übergeben
werden. Bei Argumenten des Typs @code{INT_RESULT} oder @code{REAL_RESULT}
enthält @code{lengths} immer noch die maximale Länge des Arguments (wie bei
der Initialisierungsfunktion).
@end table


@node UDF return values, UDF compiling, UDF arguments, Adding UDF
@c German node UDF-Rückgabewerte
@subsubsection Rückgabewerte und Fehlerbehandlung

@cindex UDFs, Rückgabewerte
@cindex Rückgabewerte, UDFs
@cindex Fehler, Handhabung in UDFs
@cindex Handhabung, Fehler

Die Initialisierungsfunktion sollte @code{0} zurückgeben, wenn kein Fehler
auftrat, ansonsten @code{1}. Wenn ein Fehler auftritt, sollte
@code{xxx_init()} eine null-terminierte Fehlermeldung im
@code{message}-Parameter enthalten. Die Meldung wird an den Client
übergeben. Der Meldungspuffer ist @code{MYSQL_ERRMSG_SIZE} Zeichen lang,
aber Sie sollten versuchen, die Meldung kleiner als 80 Zeichen zu halten,
damit sie auf die Anzeigebreite eines Standard-Terminals passt.

Der Rückgabewert der Hauptfunktion @code{xxx()} ist der Funktionswert, bei
@code{long long}- und @code{double}-Funktionen. Eine Zeichenkettenfunktion
sollte einen Zeiger auf das Ergebnis und die Länge der Zeichenkette in den
@code{length}-Argumenten zurückgeben.

Setzen Sie diese auf die Inhalte und Länge des Rückgabewerts. Beispiel:

@example
memcpy(result, "ergebnis_zeichenkette", 13);
*length = 13;
@end example

Der @code{result}-Puffer, der an die Berechnungsfunktionen übergeben wird,
ist 255 Byte Groß. Wenn Ihr Ergebnis dort hinein passt, müssen Sie sich um
die Speicherzuweisung für Ergebnisse nicht kümmern.

Wenn Ihre Zeichenketten-Funktion eine Zeichenkette zurückgeben muss, die
länger als 255 Bytes ist, müssen Sie den Platz dafür mit @code{malloc()} in
Ihrer @code{xxx_init()}-Funktion oder Ihrer @code{xxx()}-Funktion zuweisen
und in Ihrer @code{xxx_deinit()}-Funktion freigeben. Sie können den
zugewiesenen Speicher im @code{ptr}-Slot in der @code{UDF_INIT}-Struktur
für erneute Benutzung durch zukünftige @code{xxx()}-Aufrufe speichern.
@xref{UDF calling}.

Um einen Rückgabewert von @code{NULL} in der Hauptfunktion anzuzeigen,
setzen Sie @code{is_null} auf @code{1}:

@example
*is_null = 1;
@end example

Um eine Fehlerrückgabe in der Hauptfunktion anzuzeigen, setzen Sie den
@code{error}-Parameter auf @code{1}:

@example
*error = 1;
@end example

Wenn @code{xxx()} @code{*error} für beliebige Zeilen auf @code{1} setzt,
ist der Funktionswert der aktuellen Zeile @code{NULL}, was auch für
nachfolgende Zeilen gilt, die von dem Statement verarbeitet werden, in dem
@code{XXX()} aufgerufen wurde. (@code{xxx()} wird für nachfolgende Zeilen
nicht einmal aufgerufen.) @strong{HINWEIS:} In MySQL-Versionen vor 3.22.10
sollten Sie sowohl @code{*error} als auch und @code{*is_null} setzen:

@example
*error = 1;
*is_null = 1;
@end example


@node UDF compiling,  , UDF return values, Adding UDF
@c German node UDF kompilieren
@subsubsection Kompilieren und Installieren benutzerdefinierter Funktionen

@cindex Kompilieren, benutzerdefinierte Funktionen
@cindex UDFs, kompilieren
@cindex installieren, benutzerdefinierte Funktionen

Dateien, die UDFs implementieren, müssen auf dem Host kompiliert und
installiert werden, auf dem der Server läuft. Dieser Prozess wird unten am
Beispiel der UDF-Datei @file{udf_example.cc} beschrieben, die in der
MySQL-Quelldistribution enthalten ist. Diese Datei enthält folgende
Funktionen:

@itemize @bullet
@item
@code{metaphon()} gibt eine metaphon-Zeichenkette des
Zeichenkettenarguments zurück. Das ist etwas wie eine Soundex-Zeichenkette,
nur etwas besser für englisch angepasst.
@item
@code{myfunc_double()} gibt die Summe der ASCII-Werte der Zeichen in ihren
Argumenten zurück, geteilt durch die Summe der Längen ihrer Argumente.
@item
@code{myfunc_int()} gibt die Summe der Längen ihrer Argumente zurück.
@item
@code{sequence([const int])} gibt eine Sequenz zurück, die mit der
angegebenen Zahl startet oder mit 1, wenn keine Zahl angegeben wurde.
@item
@code{lookup()} gibt die IP-Nummer für einen Hostnamen zurück.
@item
@code{reverse_lookup()} gibt den Hostnamen für eine IP-Nummer zurück. Die
Funktion kann mit einer Zeichenkette @code{"xxx.xxx.xxx.xxx"} oder mit vier
Zahlen aufgerufen werden.
@end itemize

Eine dynamisch ladbare Datei sollte als gemeinsam nutzbare Objektdatei
kompiliert werden, etwa mit folgendem Befehl:

@example
shell> gcc -shared -o udf_example.so myfunc.cc
@end example

Die korrekten Kompiler-Optionen für Ihr System finden Sie leicht heraus,
wenn Sie diesen Befehl im @file{sql}-Verzeichnis Ihres MySQL-Quellbaums
laufen lassen:

@example
shell> make udf_example.o
@end example

Sie sollten einen Kompilierbefehl laufen lassen, der dem ähnelt, was
@code{make} anzeigt, ausser dass Sie die @code{-c}-Option kurz vor dem
Zeilenende entfernen und @code{-o udf_example.so} am Zeilenende hinzufügen
sollten. (Auf manchen Systemen können Sie @code{-c} im Befehl lassen.)

Wenn Sie ein gemeinsam genutztes Objekt kompiliert haben, das UDFs enthält,
müssen Sie es danach installieren und MySQL darüber informieren. Wenn Sie
ein gemeinsam genutztes Objekt von @file{udf_example.cc} kompilieren, wird
eine Datei etwa mit dem Namen @file{udf_example.so} erzeugt (der exakte
Name variiert von Plattform zu Plattform). Kopieren Sie diese Datei in ein
Verzeichnis, das von @code{ld} durchsucht wird, wie @file{/usr/lib}. Auf
vielen Systemen können Sie die @code{LD_LIBRARY}- oder
@code{LD_LIBRARY_PATH}-Umgebungsvariable so setzen, dass sie auf das
Verzeichnis zeigt, wo Sie Ihre UDF-Funktionsdateien haben. Das
@code{dlopen}-Handbuch sagt Ihnen, welche Variable Sie auf Ihrem System
setzen sollten. Sie sollten diese auf @code{mysql.server} oder
@code{safe_mysqld} setzen und @code{mysqld} neu starten.

Nachdem die Bibliothek installiert ist, unterrichten Sie @code{mysqld} über
die neuen Funktionen mit diesen Befehlen:

@example
mysql> CREATE FUNCTION metaphon RETURNS STRING SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_double RETURNS REAL SONAME "udf_example.so";
mysql> CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "udf_example.so";
mysql> CREATE FUNCTION lookup RETURNS STRING SONAME "udf_example.so";
mysql> CREATE FUNCTION reverse_lookup RETURNS STRING SONAME "udf_example.so";
mysql> CREATE AGGREGATE FUNCTION avgcost RETURNS REAL SONAME "udf_example.so";
@end example

Funktionen können mit @code{DROP FUNCTION} gelöscht werden:

@example
mysql> DROP FUNCTION metaphon;
mysql> DROP FUNCTION myfunc_double;
mysql> DROP FUNCTION myfunc_int;
mysql> DROP FUNCTION lookup;
mysql> DROP FUNCTION reverse_lookup;
mysql> DROP FUNCTION avgcost;
@end example

Die @code{CREATE FUNCTION}- und @code{DROP FUNCTION}-Statements
aktualisieren die Systemtabelle @code{func} in der @code{mysql}-Datenbank.
Der Funktionsname, -typ und gemeinsam genutzte Bibliothek werden in der
Tabelle gespeichert. Sie benötigen die @strong{insert}- und
@strong{delete}-Berechtigungen für die @code{mysql}-Datenbank, um
Funktionen zu erzeugen und zu löschen.

Sie sollten @code{CREATE FUNCTION} nicht benutzen, um eine Funktion
hinzuzufügen, die bereits erzeugt wurde. Wenn Sie eine Funktion erneut
installieren wollen, sollten Sie sie zuerst mit @code{DROP FUNCTION}
entfernen und dann mit @code{CREATE FUNCTION} erneut installieren. Sie
müssen so etwas zum Beispiel tun, wenn Sie eine neue Version Ihrer Funktion
kompilieren, damit @code{mysqld} die neue Version erhält. Ansonsten würde
der Server mit der alten Version weitermachen.

Aktive Funktionen werden jedes Mal neu geladen, wenn der Server startet, es
sei denn, Sie starten @code{mysqld} mit der
@code{--skip-grant-tables}-Option. In diesem Fall wird die
UDF-Initialisierung übersprungen und UDFs sind nicht verfügbar. (Eine
aktive Funktion ist eine, die mit @code{CREATE FUNCTION} geladen und nicht
mit @code{DROP FUNCTION} entfernt wurde.)


@node Adding native function,  , Adding UDF, MySQL internals
@c German node Native Funktion hinzufügen
@subsection Hinzufügen einer neuen nativen Function

@cindex hinzufügen, native Funktionen
@cindex native Funktionen, hinzufügen
@cindex Funktionen, native, hinzufügen

Die Prozedur zum Hinzufügen einer neuen nativen Funktion wird hier
beschrieben. Beachten Sie, dass Sie einer Binärdistribution keine nativen
Funktionen hinzufügen können, weil die Prozedur die Änderung des
MySQL-Quelltextes beinhaltet. Sie müssen MySQL selbst aus einer
Quelldistribution kompilieren. Beachten Sie auch, dass Sie die Prozedur
wiederholen müssen, wenn Sie auf eine andere Version von MySQL
aktualisieren (beispielsweise wenn eine neue Version herauskommt).

Um eine neue native MySQL-Funktion hinzuzufügen, gehen Sie wie folgt vor:

@enumerate
@item
Fügen Sie @file{lex.h} eine neue Zeile hinzu, die den Funktionsnamen im
@code{sql_functions[]}-Array definiert.
@item
Wenn der Funktionsprototyp einfach ist (nur keins, eins, zwei oder drei
Argumente entgegennimmt), sollten Sie in lex.h SYM(FUNC_ARG#) angeben
(wobei # die Anzahl von Argumenten ist), als zweites Argument im
@code{sql_functions[]}-Array, und eine Funktion hinzufügen, die ein
Funktionsobjekt in @file{item_create.cc} erzeugt. Sehen Sie sich als
Beispiel hierfür @code{"ABS"} und @code{create_funcs_abs()} an.

Wenn der Funktionsprototyp kompliziert ist (zum Beispiel eine variable
Anzahl von Argumenten entgegennimmt), sollten Sie zwei Zeile zu
@file{sql_yacc.yy} hinzufügen. Eine gibt das Präprozessorsymbol an, das
@code{yacc} definieren soll (das sollte am Anfang der Datei stehen).
Definieren Sie dann die Funktionsparameter und fügen Sie ein ``item'' mit
diesen Parametern zur @code{simple_expression}-Parsing-Regel hinzu. Sehen
Sie sich als Beispiel alle Vorkommen von @code{ATAN} in @file{sql_yacc.yy}
an, um zu sehen, wie das gemacht wird.
@item
Deklarieren Sie in @file{item_func.h} eine Klasse, die von
@code{Item_num_func} oder @code{Item_str_func} erbt, je nachdem, ob Ihre
Funktion eine Zahl oder eine Zeichenkette zurückgibt.
@item
Fügen Sie in @file{item_func.cc} eine der folgenden Deklarationen hinzu, je
nachdem, ob Sie eine numerische oder eine Zeichenketten-Funktion
definieren:
@example
double   Item_func_newname::val()
longlong Item_func_newname::val_int()
String  *Item_func_newname::Str(String *str)
@end example

Wenn Sie Ihr Objekt von irgend einem der Standard-Items erben (wie von
@code{Item_num_func}, müssen Sie wahrscheinlich eine der oben genannten
Funktionen definieren und das Elternobjekt sich um die anderen Funktionen
kümmern lassen. Beispielsweise definiert die @code{Item_str_func}-Klasse
eine @code{val()}-Funktion, die @code{atof()} auf dem Wert ausführt, der
von @code{::str()} zurückgegeben wurde.

@item
Sie müssen wahrscheinlich auch die folgende Objektfunktion definieren:
@example
void Item_func_newname::fix_length_und_dec()
@end example
Diese Funktion sollte zumindest @code{max_length} basierend auf den
angegebenen Argumenten berechnen. @code{max_length} ist die maximale Anzahl
von Zeichen, die die Funktion zurückgeben kann. Diese Funktion sollte auch
@code{maybe_null = 0} setzen, wenn die Hauptfunktion keinen
@code{NULL}-Wert zurückgeben kann. Die Funktion kann prüfen, ob irgend eins
der Funktionsargumente @code{NULL} zurückgeben kann, indem die Argumente
der @code{maybe_null}-Variable geprüft werden. Sehen Sie sich als typisches
Beispiel, wie das gemacht wird, @code{Item_func_mod::fix_length_and_dec}
an.
@end enumerate

Alle Funktionen müssen Thread-sicher sein (mit anderen Worten: Benutzen Sie
keine globalen oder statischen Variablen in den Funktionen, ohne sie mit
mutexes zu schützen).

Wenn Sie von @code{::val()}, @code{::val_int()} oder @code{::str()}
@code{NULL} zurückgeben wollen, sollten Sie @code{null_value} auf 1 setzen
und 0 zurückgeben.

Bei @code{::str()}-Objektfunktionen gibt es einige zusätzliche
Überlegungen, auf die man achten sollte:

@itemize @bullet
@item
Das @code{String *str}-Argument stellt einen Zeichenketten-Puffer zur
Verfügung, der benutzt werden kann, um das Ergebnis zu speichern. (Weitere
Informationen über den @code{String}-Typ finden Sie durch einen Blick in
die @file{sql_string.h}-Datei.)
@item
Die @code{::str()}-Funktion sollte die Zeichenkette zurückgeben, die das
Ergebnis enthält, oder @code{(char*) 0}, wenn das Ergebnis @code{NULL} ist.
@item
Alle aktuellen Zeichenketten-Funktionen versuchen, die Zuweisung jeglichen
Speichers zu vermeiden, ausser wenn das absolut notwendig ist!
@end itemize


@node Adding procedures, MySQL-Interna, MySQL internals, Extending MySQL
@c German node Hinzufügen von Prozeduren
@section Hinzufügen neuer Prozeduren zu MySQL

@cindex Prozeduren, hinzufügen
@cindex hinzufügen, Prozeduren
@cindex neue Prozeduren, hinzufügen

In MySQL können Sie eine Prozedur in C++ definieren, die auf Daten in einer
Anfrage zugreifen und diese ändern kann, bevor sie an den Client geschickt
werden. Die Änderung kann Zeile für Zeile oder auf @code{GROUP BY}-Ebene
geschehen.

Wir haben eine Beispiel-Prozedur in MySQL-Version 3.23 erzeugt, um zu
zeigen, was getan werden kann.

Zusätzlich empfehlen wir, dass Sie einen Blick auf 'mylua' werfen, das Sie
im Contrib-Verzeichnis finden. @xref{Contrib}. Hiermit können Sie die
LUA-Sprache benutzen, um eine Prozedur zur Laufzeit in @code{mysqld} zu
laden.



@menu
* procedure analyse::           
* Writing a procedure::         
@end menu

@node procedure analyse, Writing a procedure, Adding procedures, Adding procedures
@c German node Prozeduranalyse
@subsection Prozeduranalyse

@code{analyse([max Elemente,[max memory]])}

Diese Prozedur ist in @file{sql/sql_analyse.cc} definiert. Sie untersucht
das Ergebnis Ihrer Anfrage und gibt eine Analyse des Ergebnisses zurück:

@itemize @bullet
@item
@code{max elements} (Vorgabe 256) ist die maximale Anzahl unterschiedlicher
Werte, die @code{analyse} pro Spalte findet. Dieses wird von @code{analyse}
benutzt, um zu prüfen, ob der optimale Spaltentyp vom Typ @code{ENUM} sein
sollte.
@item
@code{max memory} (Vorgabe 8.192) ist der maximale Speicher, den
@code{analyse} pro Spalte zuweisen sollte, wenn Sie versuchen, alle
unterschiedlichen (distinct) Werte zu finden.
@end itemize

@example
SELECT ... FROM ... WHERE ... Prozeduranalyse([max elements,[max memory]])
@end example


@node Writing a procedure,  , procedure analyse, Adding procedures
@c German node Eine Prozedur schreiben
@subsection Eine Prozedur schreiben

Im Moment ist die einzige Dokumentation hierfür der Quelltext.

Sie finden alle Informationen über Prozeduren, wenn Sie folgende Dateien
untersuchen:

@itemize @bullet
@item @file{sql/sql_analyse.cc}
@item @file{sql/procedure.h}
@item @file{sql/procedure.cc}
@item @file{sql/sql_select.cc}
@end itemize


@node MySQL-Interna,  , Adding procedures, Extending MySQL
@c German node <no English equivalent>
@section MySQL-Interna

@cindex Interna
@cindex Thread

Dieses Kapitel beschreibt viele Dinge, die Sie wissen müssen, wenn Sie am
MySQL-Code arbeiten. Wenn Sie an der MySQL-Entwicklung mitarbeiten wollen,
Zugriff auf den messerscharfen Code von Zwischenversionen haben wollen,
oder einfach nur über die Entwicklung auf dem Laufenden bleiben wollen,
folgen Sie den Anweisungen unter @xref{Installing source}.
Wenn Sie an MySQL-Interna interessiert sind, sollten Sie auch
@email{internals@@lists.mysql.com} abonnieren. Das ist eine Liste mit
relativ geringem Verkehr, verglichen mit @email{mysql@@lists.mysql.com}.



@menu
* MySQL-Thread::                
* MySQL-Test-Suite::            
@end menu

@node MySQL-Thread, MySQL-Test-Suite, MySQL-Interna, MySQL-Interna
@c German node <no English equivalent>
@subsection MySQL-Thread

Der MySQL-Server erzeugt folgenden Thread:

@itemize @bullet

@item
Der TCP/IP-Verbindungs-Thread erledigt alle Verbindungsanfragen und erzeugt
einen neuen dedizierten Thread, um die Verarbeitung von Authentifizierung
und SQL-Anfragen für jede Verbindung zu handhaben.

@item
Unter Windows NT gibt es einen Named-Pipe-Handler-Thread, der dasselbe tut
wie der TCP/IP-Verbindungs-Thread, auf Named-Pipe-Verbindungsanforderungen.

@item
Der Signal-Thread handhabt alle Signale. Dieser Thread handhabt
normalerweise auch Alarme und Aufrufe von @code{process_alarm()}, um
Zeitüberschreitungen auf Verbindungen zu erzwingen, die zu lange im
Leerlauf waren.

@item
Wenn @code{mysqld} mit @code{-DUSE_ALARM_THREAD} kompiliert wird, wird ein
dedizierter Thread erzeugt, der Alarme handhabt. Das ist nur nützlich auf
manchen Systemen, auf denen es Probleme mit @code{sigwait()} gibt, oder
wenn man den @code{thr_alarm()}-Code in seiner Applikation ohne einen
dedizierten Signal-Handhabungs-Thread benutzen will.

@item
Wenn man die @code{--flush_time=#}-Option benutzt, wird ein dedizierter
Thread erzeugt, der alle Tabellen im angegebenen Intervall auf Platte
zurückschreibt.

@item
Jede Verbindung hat ihren eigenen Thread.

@item
Jede unterschiedliche Tabelle, auf der man @code{INSERT DELAYED} benutzt,
erhält ihren eigenen Thread.

@item
Wenn Sie @code{--master-host} benutzen, wird ein Slave-Replikations-Thread
gestartet, der Aktualisierungen vom Master liest und anwendet.
@end itemize

@code{mysqladmin processlist} zeigt nur die Verbindungs-, @code{INSERT
DELAYED}- und Replikations-Threads.


@node MySQL-Test-Suite,  , MySQL-Thread, MySQL-Interna
@c German node <no English equivalent>
@subsection MySQL-Test-Suite

@cindex mysqltest, MySQL-Test-Suite
@cindex mysqld testen, mysqltest

Bis vor Kurzem basierte unsere vollumfängliche Haupt-Test-Suite auf
proprietären Kundendaten und war deshalb nicht öffentlich verfügbar. Der
einzige öffentlich verfügbare Teil unseres Testprozesses bestand aus dem
@code{Crash-me}-Test, einem Perl-DBI/DBD-Benchmark, der im
@code{sql-bench}-Verzeichnis liegt, und verschiedenen Tests im
@code{tests}-Verzeichnis. Das Fehlen einer standardisierten, öffentlich
verfügbaren Test-Suite machte es unseren Benutzern und auch Entwicklern
schwer, Regressionstests auf den MySQL-Code durchzuführen. Um das Problem
anzugehen, haben wir ein neues Testsystem geschaffen, das ab Version
3.23.29 den Quell- und Binärdistributionen beiliegt.

Der aktuelle Satz von Testfällen testet nicht alles in MySQL, sollte aber
die offensichtlichsten Bugs im SQL-Verarbeitungscode offen legen, sowie
Betriebssystem- und Bibliotheks-Probleme, und er testet recht gründlich die
Replikation. Unser letztliches Ziel ist es, dass die Tests 100% des Codes
abdecken. Beiträge zu unserer Test-Suite sind herzlich willkommen,
besonders Tests, die die Funktionalität untersuchen, die für Ihr System
kritisch ist, weil das sicherstellt, dass alle zukünftigen MySQL-Releases
mit Ihren Applikationen funktionieren.



@menu
* mysqltest laufen lassen::     
* MySQL-Tests erweitern::       
* mysqltest-Bugs berichten::    
@end menu

@node mysqltest laufen lassen, MySQL-Tests erweitern, MySQL-Test-Suite, MySQL-Test-Suite
@c German node <no English equivalent>
@subsubsection Die MySQL-Test-Suite laufen lassen

Das Testsystem besteht aus einem Test-Sprachinterpreter (@code{mysqltest}),
einem Shell-Skript, um alle Tests laufen zu lassen
tests(@code{mysql-test-run}), den eigentlichen Testfällen, die in einer
speziellen Testsprache geschrieben sind, und ihren erwarteten Ergebnissen.
Um die Test-Suite nach dem Bauen auf Ihrem System laufen zu lassen, geben
Sie @code{make test} oder @code{mysql-test/mysql-test-run} von der Wurzel
der Quellinstallation aus ein. Wenn Sie eine Binärdistribution installiert
haben, wechseln Sie (@code{cd}) zur Wurzel der Installation (zum Beispiel
@code{/usr/local/mysql}) und geben @code{scripts/mysql-test-run} ein. Alle
Tests sollten erfolgreich durchlaufen. Wenn nicht, sollten Sie versuchen,
den Grund herauszufinden, und das Problem zu berichten, wenn es ein Bug in
MySQL ist. @xref{mysqltest-Bugs berichten}.

Wenn eine Kopie von @code{mysqld} auf Ihrer Maschine läuft, wo Sie die
Test-Suite laufen lassen wollen, müssen Sie ihn nicht anhalten, solange er
nicht die Ports @code{9306} und @code{9307} benutzt. Wenn einer dieser
Ports belegt ist, sollten Sie @code{mysql-test-run} editieren und die Werte
des Master- und / oder Slave-Ports auf verfügbare Ports ändern.

Sie können einen einzelnen Testfall mit @code{mysql-test/mysql-test-run
test_name} laufen lassen.

Wenn ein Test fehlschlägt, sollten Sie versuchen, @code{mysql-test-run} mit
der @code{--force}-Option laufen zu lassen, um zu prüfen, ob irgend ein
weiterer Test fehlschlägt.


@node MySQL-Tests erweitern, mysqltest-Bugs berichten, mysqltest laufen lassen, MySQL-Test-Suite
@c German node <no English equivalent>
@subsubsection Die MySQL-Test-Suite erweitern

Sie können die @code{mysqltest}-Sprache benutzen, um Ihre eigenen Testfälle
zu schreiben. Leider gibt es noch keine komplette Dokumentation dafür - das
soll in Kürze aber der Fall sein. Sie können sich jedoch die aktuellen
Testfälle ansehen und sie als Beispiel benutzen. Folgende Punkte sollen
Ihnen beim Start helfen:

@itemize @bullet
@item
Die Tests liegen in @code{mysql-test/t/*.test}

@item
Ein Testfall besteht aus @code{;}-begrenzten Statements und ist ähnlich der
Eingabe in den @code{mysql}-Kommandozeilen-Client. Ein Statement ist
vorgabemäßig eine Anfrage, die an den MySQL-Server geschickt werden soll,
es sei denn, es wird als interner Befehl erkannt (zum Beispiel
@code{sleep}).

@item
Alle Anfragen, die Ergebnisse produzieren, zum Beispiel @code{SELECT},
@code{SHOW}, @code{EXPLAIN} usw., müssen mit
@code{@@/pfad/zu/ergebnis/datei} beginnen. Die Datei muss die erwarteten
Ergebnisse enthalten. Eine einfache Art, die Ergebnisdatei zu erzeugen,
ist, @code{mysqltest -r < t/test-case-name.test} vom
@code{mysql-test}-Verzeichnis aus laufen zu lassen und dann die erzeugten
Ergebnisdateien zu editieren und sie - falls nötig - an die erwartete
Ausgabe anzupassen. Seien Sie in diesem Fall sehr vorsichtig, keine
unsichtbaren Zeichen hinzuzufügen oder zu löschen - stellen Sie sicher,
dass Sie nur den Text ändern und / oder Zeilen löschen. Wenn Sie eine Zeile
einfügen müssen, achten Sie darauf, dass die Felder mit einem harten
Tabulator-Zeichen getrennt sind und dass es ein hartes Tabulator-Zeichen am
Zeilenende gibt. Gegebenfalls sollten Sie @code{od -c} benutzen, um sich zu
vergewissern, dass Ihr Texteditor beim Editieren nichts durcheinander
gebracht hat. Wir hoffen natürlich, dass Sie die Ausgabe von
@code{mysqltest -r} nie editieren müssen, weil das nur der Fall ist, wenn
Sie einen Bug finden.

@item
Um mit unserer Einrichtung konsistent zu sein, sollten Sie Ihre
Ergebnisdateien ins @code{mysql-test/r}-Verzeichnis stellen und sie
@code{test_name.result} nennen. Wenn der Test mehr als ein Ergebnis
erzeugt, sollten Sie @code{test_name.a.result}, @code{test_name.b.result}
usw. verwenden.

@item
Wenn ein Statement einen Fehler zurückgibt, sollten Sie die Zeile vor dem
Statement mit @code{--error fehler_nummer} kennzeichnen. Die Fehlernummer
kann eine Auflistung möglicher Fehlerzahlen sein, getrennt durch
@code{','}.

@item
Wenn Sie einen Replikations-Testfall schreiben, sollten Sie in die erste
Zeile der Testdatei @code{source include/master-slave.inc;} schreiben. Um
zwischen Master und Slave umzuschalten, benutzen Sie @code{connection
master;} und @code{connection slave;}. Wenn Sie etwas auf einer
abwechselnden Verbindung machen müssen, können Sie @code{connection
master1;} für den Master und @code{connection slave1;} für den Slave
eingeben.

@item
Wenn Sie etwas in einer Schleife ausführen müssen, können Sie zum Beispiel
folgendes tun:
@example
let $1=1000;
while ($1)
@{
 # machen Sie Ihre Anfragen hier
 dec $1;
@}
@end example

@item
Um zwischen Anfragen zu schlafen, benutzen Sie den @code{sleep}-Befehl. Er
unterstützt Bruchteile von Sekunden, daher können Sie zum Beispiel
@code{sleep 1.3;} ausführen, um 1,3 Sekunden zu schlafen.

@item
Um den Slave für Ihren Testfall mit zusätzlichen Optionen laufen zu lassen,
geben Sie diese im Kommandozeilenformat in
@code{mysql-test/t/test_name-slave.opt} ein. Für den Master geben Sie sie
in @code{mysql-test/t/test_name-master.opt} ein.

@item
Wenn Sie eine Frage zur Test-Suite haben oder einen Testfall beisteuern
wollen, schicken Sie eine E-Mail an @email{Interna@@lists.mysql.com}. Weil
die Liste keine Dateianhänge akzeptiert, sollten Sie alle relevanten
Dateien per FTP an @url{ftp://support.mysql.com/pub/mysql/Incoming}
schicken.

@end itemize


@node mysqltest-Bugs berichten,  , MySQL-Tests erweitern, MySQL-Test-Suite
@c German node <no English equivalent>
@subsubsection Bugs in der MySQL-Test-Suite berichten

Wenn Ihre MySQL-Version die Test-Suite nicht fehlerfrei durchläuft, sollten
Sie folgendes tun:

@itemize @bullet
@item
Schicken Sie keinen Bug-Bericht, bevor Sie so weit wie möglich
herausgefunden haben, was schief ging! Benutzen Sie für den Bug-Bericht
bitte das @code{mysqlbug}-Skript, so dass wir Informationen über Ihr System
und die @code{MySQL}-Version erhalten. @xref{Bug reports}.
@item
Stellen Sie sicher, dass die Ausgabe von @code{mysql-test-run} beiliegt,
sowie alle Inhalte aller @code{.reject}-Dateien im
@code{mysql-test/r}-Verzeichnis.
@item
Wenn ein Test in der Test-Suite fehlschlägt, prüfen Sie, ob der Test auch
fehlschlägt, wenn er allein laufen gelassen wird:

@example
cd mysql-test
mysql-test-run --local test-name
@end example

Wenn das fehlschlägt, sollten Sie MySQL mit @code{--with-debug}
konfigurieren und @code{mysql-test-run} mit der @code{--debug}-Option
laufen lassen. Wenn auch das fehlschlägt, schicken Sie dei Trace-Datei
@file{var/tmp/master.trace} an ftp://support.mysql.com/pub/mysql/secret, so
dass wir sie untersuchen können. Denken Sie bitte daran, eine volle
Beschreibung Ihres Systems beizufügen sowie die Version Ihrer
mysqld-Binärdatei und wie Sie sie kompiliert haben.

@item
Versuchen Sie auch, @code{mysql-test-run} mit der @code{--force}-Option
laufen zu lassen, um zu sehen, ob auch andere Tests fehlschlagen.

@item
Wenn Sie MySQL selbst kompiliert haben, sehen Sie im Handbuch nach, wie
MySQL auf Ihrer Plattform kompiliert wird, oder benutzen Sie vorzugsweise
eine der Binärdateien, die wir für Sie kompiliert haben und die Sie unter
@uref{http://www.mysql.com/downloads/} finden. Alle unsere
Standard-Binärdateien sollten die Test-Suite fehlerfrei durchlaufen!

@item
Wenn Sie einen Fehler wie @code{Result length mismatch} oder @code{Result
content mismatch} erhalten, heißt das, dass die Ausgabe des Tests nicht
genau mit der erwarteten Ausgabe übereinstimmt. Das könnte ein Bug in MySQL
sein, könnte aber auch heißen, dass Ihre mysqld-Version unter bestimmten
Umständen leicht abweichende Ausgaben erzeugt.

Fehlgeschlagene Testergebnisse werden in eine Datei mit demselben Namen wie
die Ergebnisdatei, mit der Endung @code{.reject}, gestellt. Wenn Ihr
Testfall fehlschlägt, sollten Sie ein DIFF beider Dateien vornehmen. Wenn
Sie nicht erkennen können, in welcher Hinsicht sie sich unterscheiden,
untersuchen Sie beide mit @code{od -c} und prüfen Sie auch ihre Längen.

@item
Wenn ein Testfall völlig fehlschlägt, sollten Sie die Log-Dateien im
@code{mysql-test/var/log}-Verzeichnis nach Hinweisen untersuchen, was
schief ging.

@item
Wenn Sie MySQL mit Debugging kompiliert haben, können Sie versuchen, das zu
debuggen, indem Sie @code{mysql-test-run} mit den @code{--gdb}- und / oder
@code{--debug}-Optionen laufen lassen.
@xref{Making trace files}.

Wenn Sie MySQL nicht für Debugging kompiliert haben, sollten Sie das besser
tun. Geben Sie einfach die @code{--with-debug}-Option für @code{configure}
an! @xref{Installing source}.
@end itemize




@node Problems, Benutzer, Extending MySQL, Top
@c German node Probleme
@appendix Probleme und häufige Fehler

@cindex Probleme, häufige Fehler
@cindex Fehler, häufige


Dieses Kapitel listet einige gebräuchliche Probleme und Fehlermeldungen
auf, denen Benutzer in die Arme laufen. Sie lernen herauszufinden, was das
Problem ist und wie Sie es lösen. Hier finden sich auch korrekte Lösungen
einiger häufiger Probleme.


@menu
* What is crashing::            
* Common errors::               
* Installation Issues::         
* Administration Issues::       
* Query Issues::                
* Table Definition Issues::     
@end menu

@node What is crashing, Common errors, Problems, Problems
@c German node Was ist ein Absturz
@appendixsec Wie man feststellt, was Probleme verursacht

Wenn Sie Probleme bekommen, sollten Sie als erstes herausfinden, welches
Programm oder Hardware-Teil die Probleme verursacht:

@itemize @bullet
@item
Wenn Sie eins der folgenden Symptome beobachten, gibt es wahrscheinlich ein
Hardware- (Speicher, Hauptplatine, Prozessor oder Festplatte) oder
Kernel-Problem:
@itemize @minus
@item
Die Tastatur funktioniert nicht. Normalerweise können Sie das durch Drücken
der Feststelltaste (Caps Lock) überprüfen. Wenn sich die Anzeigeleuchte
beim Drücken nicht an- und ausschaltet, müssen Sie Ihre Tastatur ersetzen.
(Bevor Sie das tun, sollten Sie Ihren Computer neu starten und alle
Kabelverbindungen zur Tastatur überprüfen.)
@item
Der Mauszeiger bewegt sich nicht.
@item
Die Maschine antwortet auf entfernte Ping-Versuche nicht.
@item
Andere Programme, die mit MySQL nichts zu tun haben, funktionieren nicht
korrekt.
@item
Wenn Ihr System unerwartet neu startet (ein fehlerhaftes Programm auf
Benutzerebene sollte NIE in der Lage sein, Ihr System zum Absturz zu
bringen).
@end itemize

In solchen Fällen sollten Sie zunächst alle Kabel überprüfen und
Diagnoseprogramme laufen lassen, um Ihre Hardware zu untersuchen! Sie
sollten auch prüfen, ob Patches, Aktualisierungen oder Service-Packs für
Ihre Betriebssystem verfügbar sind, die Ihre Probleme möglicherweise lösen.
Prüfen Sie auch, ob Ihre Bibliotheken (wie glibc) aktuell sind.

Es ist immer eine gute Idee, eine Maschine mit ECC-Speicher zu benutzen, um
Speicherprobleme frühzeitig zu erkennen!
@item
Wenn Ihre Tastatur gesperrt ist, können Sie das eventuell beheben, indem
Sie sich von einer anderen Maschine aus verbinden und @code{kbd_mode -a}
ausführen.

@item
Untersuchen Sie Ihre System-Log-Datei (/var/log/messages oder ähnliches)
nach Gründen für Ihre Probleme. Wenn Sie glauben, dass das Problem an MySQL
liegt, sollten Sie auch die Log-Dateien von MySQL überprüfen.
@xref{Update log}.

@item
Wenn Sie nicht glauben, ein Hardware-Problem zu haben, sollten Sie
herausfinden, welches Programm die Probleme verursacht.

Probieren Sie @code{top}, @code{ps}, @code{taskmanager} oder ein ähnliches
Programm, um zu prüfen, welches Programm die gesamte Prozessorzeit
konsumiert oder die Maschine blockiert.

@item
Prüfen Sie mit @code{top}, @code{df} oder einem ähnlichen Programm, wenn
Sie keinen freien Arbeitsspeicher, Festplattenspeicher, verfügbare
Datei-Handler oder eine andere kritische Ressource mehr haben.

@item
Wenn das Problem an einem aus dem Ruder gelaufenen Prozess liegt, können
Sie versuchen, diesen zu killen. Wenn er nicht sterben will, gibt es
wahrscheinlich einen Bug im Betriebssystem.
@end itemize

Wenn Sie alle anderen Möglichkeiten untersucht und ausgeschlossen haben und
zur Schlussfolgerung gekommen sind, dass die Probleme durch den
MySQL-Server oder ein MySQL-Client-Programm verursacht werden, ist es an
der Zeit, einen Bug-Bericht für die Mailing-Liste oder unser Support-Team
zu schreiben. Machen Sie im Bug-Bericht eine sehr detaillierte
Beschreibung, wie sich Ihr System verhält und was Sie vermuten, was
passiert. Sie sollten auch angeben, warum Sie denken, dass MySQL die
Probleme verursacht. Ziehen Sie alle Situationen in diesem Kapitel in
Betracht. Geben Sie genau an, welche Probleme wie auftauchen, wenn Sie Ihr
System untersuchen. Benutzen Sie Kopieren und Einfügen, wenn Sie Ausgaben
und / oder Fehlermeldungen von Programmen oder aus Log-Dateien beifügen!

Versuchen Sie detailliert zu beschreiben, welches Programm nicht
funktioniert, und alle Symptome, die Sie sehen! In der Vergangenheit haben
wir viele Bug-Berichte erhalten, in denen schlicht steht, dass "das System
nicht funktioniert". Daraus können wir natürlich keinerlei Informationen
ziehen, wie das Problem gelöst werden könnte.

Wenn ein Programm fehlschlägt, ist es immer nützlich, folgendes zu wissen:

@itemize @bullet
@item
Hat das fragliche Programm einen Segmentation-Fehler verursacht (Core
Dump)?
@item
Nimmt das Programm sich die gesamte Prozessorleistung? Überprüfen Sie das
mit @code{top}. Lassen Sie das Programm eine Weile laufen, denn vielleicht
evaluiert es gerade nur etwas Schwieriges.
@item
Wenn der @code{mysqld}-Server Probleme verursacht, können Sie dann
@code{mysqladmin -u root ping} oder @code{mysqladmin -u root processlist}
ausführen?
@item
Was sagt ein Client-Programm (zum Beispiel @code{mysql}), wenn Sie
versuchen, sich mit dem MySQL-Server zu verbinden? Bricht der Client
zusammen? Erhalten Sie von diesem Programm irgend welche Ausgaben?
@end itemize

Wenn Sie einen Bug-Bericht senden, sollten Sie immer den Angaben folgen,
die in diesem Handbuch beschrieben sind. @xref{Asking questions}.


@node Common errors, Installation Issues, What is crashing, Problems
@c German node Häufige Fehler
@appendixsec Einige gebräuchliche Fehler bei der Benutzung von MySQL

@cindex errors, Auflistung



Dieser Abschnitt listet einige Fehler auf, die Benutzer häufig erhalten.
Hier finden Sie Beschreibungen dieser Fehler und wie man die Probleme löst.


@menu
* Error Access denied::         
* Gone away::                   
* Can not connect to server::   
* Blocked host::                
* Too many connections::        
* Non-transactional tables::    
* Out of memory::               
* Packet too large::            
* Communication errors::        
* Full table::                  
* Cannot create::               
* Commands out of sync::        
* Ignoring user::               
* Cannot find table::           
* Cannot initialize character set::  
* Not enough file handles::     
@end menu

@node Error Access denied, Gone away, Common errors, Common errors
@c German node Zugriff-verweigert-Fehler
@appendixsubsec @code{Access denied}-Fehler

@cindex Fehler, Zugriff verweigert
@cindex Probleme, Zugriff-verweigert-Fehler
@cindex access denied

@xref{Privileges}, insbesondere @xref{Access denied}.


@node Gone away, Can not connect to server, Error Access denied, Common errors
@c German node Weg gegangen
@appendixsubsec @code{MySQL server has gone away}-Fehler

Dieser Abschnitt behandelt auch den verwandten @code{Lost connection to
server during query}-Fehler.

Der häufigste Grund für den @code{MySQL server has gone away}-Fehler ist
eine Zeitüberschreitung, nach der der Server die Verbindung schloss.
Vorgabemäßig schließt der Server die Verbindung nach 8 Stunden, wenn
nichts passiert ist. Sie können diesen Wert mit der
@code{wait_timeout}-Variablen ändern, die beim Start von @code{mysqld}
gesetzt wird.

Ein weiterer häufiger Grund für den @code{MySQL server has gone
away}-Fehler ist das Absetzen eines ``close'' auf Ihre MySQL-Verbindung mit
dem anschließenden Versuch, auf der geschlossenen Verbindung eine Anfrage
abzusetzen.

Sie können überprüfen, ob der MySQL-Server gestorben ist, indem Sie
@code{mysqladmin version} ausführen und die Uptime untersuchen.

Wenn Sie ein Skript haben, müssen Sie die Anfrage lediglich noch einmal für
den Client absetzen, um eine automatische Neuverbindung zu machen.

Normalerweise können Sie folgende Fehler-Codes für diesen Fall abfragen
(die Betriebssystem-abhängig sind):

@multitable @columnfractions .3 .7
@item @code{CR_SERVER_GONE_ERROR} @tab Der Client konnte keine Anfrage an
den Server schicken.
@item @code{CR_SERVER_LOST} @tab  Der Client erhielt beim Schreiben zum
Server keinen Fehler, bekam aber keine vollständige (oder überhaupt keine)
Antwort.
@end multitable

Sie erhalten diese Fehler auch, wenn Sie eine Anfrage zum Server schicken,
die falsch oder zu Groß ist. Wenn @code{mysqld} ein Paket erhält, das zu
Groß oder nicht in Ordnung ist, nimmt er hat, dass etwas mit dem Client
schief ging und schließt die Verbindung. Wenn Sie große Anfragen brauchen
(beispielsweise wenn Sie mit @code{BLOB}-Spalten arbeiten), können Sie die
Anfragebeschränkung erhöhen, indem Sie @code{mysqld} mit der @code{-O
max_allowed_packet=#}-Option starten (Vorgabe 1 MB). Der zusätzliche
Speicher wird bei Bedarf zugewiesen, daher benutzt @code{mysqld} nur dann
mehr Speicher, wenn Sie eine große Anfrage ausführen oder wenn
@code{mysqld} ein großes Ergebnis zurückgeben muss!


@node Can not connect to server, Blocked host, Gone away, Common errors
@c German node Keine Verbindung zum Server
@appendixsubsec @code{Can't connect to [local] MySQL server}-Fehler

Ein MySQL-Client unter Unix kann sich auf zwei unterschiedliche Arten mit
dem @code{mysqld}-Server verbinden: Unix-Sockets, die sich durch eine Datei
im Dateisystem verbinden (Vorgabe @file{/tmp/mysqld.sock}) oder über
TCP/IP, was sich über eine Portnummer verbindet. Unix-Sockets sind
schneller als TCP/IP, können aber nur benutzt werden, wenn man sich zu
einem Server auf demselben Computer verbindet. Unix-Sockets werden benutzt,
wenn Sie keinen Hostnamen oder den speziellen Hostnamen @code{localhost}
angeben.

Unter Windows können Sie sich nur mit TCP/IP verbinden, wenn der
@code{mysqld}-Server unter Windows 95 / 98 läuft. Wenn er unter Windows NT
läuft, können Sie sich auch mit Named Pipes verbinden. Der Name der Named
Pipe ist MySQL. Wenn Sie bei der Verbindung zu @code{mysqld} keinen
Hostnamen angeben, versucht ein MySQL-Client zuerst, sich über die Named
Pipe zu verbinden. Erst wenn das fehlschlägt, versucht er, sich über den
TCP/IP-Port zu verbinden. Sie können die Benutzung von Named Pipes unter
Windows erzwingen, indem Sie @code{.} als Hostnamen benutzen.

Der Fehler (2002) @code{Can't connect to ...} bedeutet normalerweise, dass
auf dem System kein MySQL-Server läuft oder dass Sie eine falsche
Socket-Datei oder einen falschen TCP/IP-Port bei der Verbindung mit dem
@code{mysqld}-Server benutzen.

Prüfen Sie zuerst mit @code{ps} oder dem Task-Manager unter Windows, ob es
einen laufenden Prozess namens @code{mysqld} auf Ihrem Server gibt! Wenn es
keinen @code{mysqld}-Prozess gibt, sollten Sie einen starten. @xref{Starting server}.

Wenn ein @code{mysqld}-Prozess läuft, können Sie den Server mit diesen
unterschiedlichen Verbindungen überprüfen (die Portnummer und
Socket-Pfadnamen können auf Ihrem System natürlich anders sein):

@example
shell> mysqladmin version
shell> mysqladmin variables
shell> mysqladmin -h `hostname` version variables
shell> mysqladmin -h `hostname` --port=3306 version
shell> mysqladmin -h 'ip_ihres_hosts' version
shell> mysqladmin --socket=/tmp/mysql.sock version
@end example

Beachten Sie die Benutzung umgedrehter Anführungszeichen statt normaler
Anführungszeichen beim @code{hostname}-Befehl. Diese verursachen, dass die
Ausgabe durch @code{hostname} (das heißt des aktuellen Hostnamens) im
@code{mysqladmin}-Befehl ersetzt wird.

Hier sind einige Gründe für das Auftreten des @code{Can't connect to local
MySQL server}-Fehlers:

@itemize @bullet
@item
@code{mysqld} läuft nicht.
@item
Sie fahren auf einem System, das MIT-pThread verwendet. Wenn Sie auf einem
System fahren, das keine nativen Threads hat, benutzt @code{mysqld} das
MIT-pThread-Paket. @xref{Which OS}. Nicht alle
MIT-pThread-Versionen unterstützen jedoch Unix-Sockets. Auf einem System
ohne Socket-Unterstützung müssen Sie den Hostnamen immer explizit angeben,
wenn Sie sich mit dem Server verbinden. Benutzen Sie diesen Befehl, um die
Verbindung zum Server zu überprüfen:
@example
shell> mysqladmin -h `hostname` version
@end example
@item
Jemand hat den Unix-Socket entfernt, den @code{mysqld} benutzt (Vorgabe
@file{/tmp/mysqld.sock}). Vielleicht gibt es einen @code{cron}-Job, der den
MySQL-Socket entfernt (beispielsweise ein Job, der alte Dateien aus dem
@file{/tmp}-Verzeichnis entfernt). Sie können  @code{mysqladmin version}
laufen lassen und überprüfen, dass der Socket, den @code{mysqladmin}
versucht zu benutzen, tatsächlich existiert. Die Problemlösung besteht in
diesem Fall darin, den @code{cron}-Job so zu ändern, dass er nicht
@file{mysqld.sock} entfernt oder den Socket an andere Stelle zu platzieren.
@xref{Problems with mysql.sock}.
@item
Sie haben den @code{mysqld}-Server mit der
@code{--socket=/pfad/zu/socket}-Option gestartet. Wenn Sie den
Socket-Pfadnamen zum Server ändern, müssen Sie auch die MySQL-Clients
darüber unterrichten. Das können Sie tun, indem Sie den Socket-Pfad als
Argument an den Client übergeben. @xref{Problems with mysql.sock}.
@item
Sie benutzen Linux und ein Thread ist gestorben (Core Dump). In diesem Fall
müssen Sie den anderen @code{mysqld}-Thread killen (beispielsweise mit dem
@code{mysql_zap}-Skript), bevor Sie einen neuen MySQL-Server starten
können. @xref{Crashing}.
@item
Eventuell haben Sie keine Lese- und Schreibberechtigungen entweder für das
Verzeichnis, in dem die Socket-Datei liegt, oder keine Berechtigung für die
Socket-Datei selbst. In diesem Fall können Sie entweder die Berechtigung
für die Datei und / oder das Verzeichnis ändern oder @code{mysqld} neu
starten, so dass er ein Verzeichnis benutzt, auf das Sie Zugriff haben.
@end itemize

Wenn Sie die Fehlermeldung @code{Can't connect to MySQL server on
ein_hostname} erhalten, können Sie folgendes probieren, um den Grund des
Problems herauszufinden:

@itemize @bullet
@item
Überprüfen Sie, ob der Server hochgefahren ist, indem Sie @code{telnet
ihr_hostname tcp-ip-port-nummer} ausführen und einige Male die Eingabetaste
(@code{RETURN}) drücken. Wenn es auf diesem Port einen laufenden
MySQL-Server gibt, sollten Sie eine Antwort erhalten, die die
Versionsnummer des Server enthält. Wenn Sie einen Fehler wie @code{telnet:
Unable to connect to remote host: Connection refused} erhalten, gibt es auf
diesem Port keinen laufenden Server.
@item
Versuchen Sie, sich mit dem @code{mysqld}-Daemon auf der lokalen Maschine
zu verbinden und prüfen Sie den TCP/IP-Port, den @code{mysqld} laut
Konfiguration benutzen soll (Variable @code{port}), mit @code{mysqladmin
variables}.
@item
Prüfen Sie, ob Ihr @code{mysqld}-Server nicht gestartet wurde, indem Sie
die @code{--skip-networking}-Option verwenden.
@end itemize


@node Blocked host, Too many connections, Can not connect to server, Common errors
@c German node Blockierter Host
@appendixsubsec @code{Host '...' is blocked}-Fehler

Wenn Sie einen Fehler wie folgt erhalten:

@example
Host 'hostname' is blocked because of too many connection errors.
Unblock with 'mysqladmin flush-hosts'
@end example

Bedeutet das, dass @code{mysqld} zu viele (@code{max_connect_errors})
Verbindungsanforderungen vom Host @code{'hostname'} erhalten hat, die
mittendrin unterbrochen wurden. Nach @code{max_connect_errors}
fehlgeschlagenen Anfragen nimmt @code{mysqld} an, dass etwas nicht stimmt
(wie ein Angriff eines Crackers) und blockiert weitere
Verbindungsanforderungen von der Site, bis jemand @code{mysqladmin
flush-hosts} ausführt.

Vorgabemäßig blockiert @code{mysqld} einen Host nach 10
Verbindungsfehlern. Das können Sie leicht durch Starten des Servers wie
folgt ändern:

@example
shell> safe_mysqld -O max_connect_errors=10000 &
@end example

Beachten Sie, dass Sie bei dieser Fehlermeldung für einen gegebenen Host
zunächst prüfen sollten, ob etwas mit den TCP/IP-Verbindungen von diesem
Host aus nicht stimmt. Wenn Ihre TCP/IP-Verbindungen nicht funktionieren,
nützt es Ihnen nichts, den Wert der @code{max_connect_errors}-Variablen
heraufzusetzen!


@node Too many connections, Non-transactional tables, Blocked host, Common errors
@c German node Zu viele Verbindungen
@appendixsubsec @code{Too many connections}-Fehler

Wenn Sie beim Verbindungsversuch den Fehler @code{Too many connections}
erhalten, heißt das, dass es bereits @code{max_connections} Clients gibt,
die mit dem @code{mysqld}-Server verbunden sind.

Wenn Sie mehr Verbindungen als die Vorgabe (100) benötigen, können Sie 
@code{mysqld} mit einem größeren Wert für die
@code{max_connections}-Variable neu starten.

Beachten Sie, dass @code{mysqld} tatsächlich (@code{max_connections}+1)
Clients für Verbindungen zuläßt. Die letzte Verbindung wird für einen
Benutzer mit der @strong{process}-Berechtigung reserviert. Wenn Sie keinem
normalen Benutzer diese Berechtigung geben (diese sollte sie nie
benötigen), kann sich ein Administrator mit dieser Berechtigung einloggen
und @code{SHOW PROCESSLIST} benutzen, um herauszufinden, was schief geht.
@xref{SHOW}.

Die maximale Anzahl von Verbindungen ist davon abhängig, wie gut die
Thread-Bibliothek auf der Plattform ist. Linux oder Solaris sollten in der
Lage sein, 500 bis 1000 gleichzeitige Verbindungen zu unterstützen, abhängig
davon, wie viel Arbeitsspeicher Sie haben und was Ihre Clients ausführen.


@node Non-transactional tables, Out of memory, Too many connections, Common errors
@c German node Nicht transaktionale Tabellen
@appendixsubsec @code{Some non-transactional changed tables couldn't be rolled back}-Fehler

@cindex Nicht transaktionale Tabellen

Wenn Sie den Fehler @code{Warning: Some non-transactional changed tables
couldn't be rolled back} erhalten, wenn Sie ein @code{ROLLBACK} versuchen,
bedeutet das, dass einige der bei der Transaktion benutzten Tabellen keine
Transaktionen unterstützen. Diese nicht transkationalen Tabellen werden vom
@code{ROLLBACK}-Statement nicht betroffen.

Der typischste Fall, bei dem dieser Fehler auftritt, ist, wenn Sie versucht
haben, eine Tabelle von einem Typ zu erzeugen, der von Ihrer
@code{mysqld}-Binärdatei nicht unterstützt wird. Wenn @code{mysqld} einen
Tabellentyp nicht unterstützt (oder wenn der Tabellentyp durch die
Startoption ausgeschaltet ist), wird statt dessen ein Tabellentyp erzeugt,
der dem angeforderten am nächsten entspricht (wahrscheinlich
@code{MyISAM}.

Sie können den Tabellentyp für eine Tabelle wie folgt überprüfen:

@code{SHOW TABLE STATUS LIKE 'tabelle'}. @xref{SHOW TABLE STATUS}.

Sie können die Erweiterungen, die Ihre @code{mysqld}-Binärdatei
unterstützt, wie folgt überprüfen:

@code{show variables like 'have_%'}. @xref{SHOW VARIABLES}.


@node Out of memory, Packet too large, Non-transactional tables, Common errors
@c German node Kein Speicher verfügbar
@appendixsubsec @code{No free memory}-Fehler

Wenn Sie eine Anfrage ausführen und etwas wie folgenden Fehler erhalten:

@example
mysql: No free memory at line 42, 'malloc.c'
mysql: needed 8136 byte (8k), memory in use: 12481367 Bytes (12189k)
ERROR 2008: MySQL client ran No free memory
@end example

Beachten Sie, dass sich dieser Fehler auf den MySQL-Client @code{mysql}
bezieht. Der Grund für diesen Fehler ist einfach, dass der Client nicht
genug freien Speicher hat, um das gesamte Ergebnis zu speichern.

Um das Problem zu beheben, prüfen Sie zunächst, ob Ihre Anfrage korrekt
ist. Sollte sie vernünftigerweise so viele Zeilen zurückgeben? Wenn das der
Fall ist, können Sie @code{mysql --quick} benutzen, was
@code{mysql_use_result()} benutzt, um die Ergebnismenge abzurufen.
Hierdurch wird Last vom Client auf den Server verlagert.


@node Packet too large, Communication errors, Out of memory, Common errors
@c German node Paket zu Groß
@appendixsubsec @code{Packet too large}-Fehler

Wenn ein MySQL-Client oder der @code{mysqld}-Server ein Paket erhält, das
größer als @code{max_allowed_packet} Bytes ist, gibt er einen @code{Packet
too large}-Fehler aus und schließt die Verbindung.

Wenn Sie den @code{mysql}-Client benutzen, müssen Sie einen größeren
Puffer angeben, indem Sie den Client mit @code{mysql
--set-variable=max_allowed_packet=8M} starten.

Wenn Sie andere Clients benutzen, die die Angabe der maximalen Paketgröße
nicht zulassen (wie @code{DBI}), müssen Sie die Paketgröße beim Start des
Servers setzen. Sie können eine Kommandozeilenoption für @code{mysqld}
benutzen, um @code{max_allowed_packet} auf eine höhere Größe zu setzen.
Wenn Sie zum Beispiel beabsichtigen, die volle Länge eines @code{BLOB} in
eine Tabelle zu speichern, müssen Sie den Server mit der
@code{--set-variable=max_allowed_packet=16M}-Option starten.

Sie können merkwürdige Probleme mit großen Paketen erhalten, wenn Sie
große Blobs benutzen, aber @code{mysqld} keinen Zugriff auf genug Speicher
gegeben haben, um die Anfrage zu handhaben. Wenn Sie vermuten, dass das der
Fall ist, versuchen Sie, am Anfang des @code{safe_mysqld}-Skripts
@code{ulimit -d 256000} hinzuzufügen, und starten Sie @code{mysqld} neu.

@node Communication errors, Full table, Packet too large, Common errors
@c German node Kommunikationsfehler
@appendixsubsec Kommunikationsfehler / Abgebrochene Verbindung

@cindex Abgebrochene Clients
@cindex Abgebrochene Verbindung
@cindex Verbindung, abgebrochen

Ab @code{MySQL 3.23.40} erhalten Sie den @code{Aborted connection}-Fehler
nur dann, wenn Sie @code{mysqld} mit @code{--warnings} starten.

Wenn Sie Fehler wie den folgenden in Ihrer Fehler-Log-Datei entdecken:

@example
010301 14:38:23  Aborted connection 854 to db: 'Benutzer' user: 'josh'
@end example

@xref{Error log}.

Bedeutet das, dass eins der folgenden Dinge passiert ist:

@itemize @bullet
@item
Das Client-Programm rief vor dem Beenden nicht @code{mysql_close()} auf.
@item
Der Client schlief länger als @code{wait_timeout} oder
@code{interactive_timeout}, ohne Anfragen auszuführen.
@c German FIX unsplit @xref
@xref{SHOW VARIABLES}.
@item
Das Client-Programm wurde abrupt während einer Übertragung beendet.
@end itemize

Wenn das oben Genannte passiert, wird die Servervariable
@code{Aborted_clients} heraufgezählt.

Die Servervariable @code{Aborted_connects} wird in folgenden Fällen
heraufgezählt:

@itemize @bullet
@item
Wenn ein Verbindungspaket nicht die richtigen Informationen enthält.
@item
Wenn der Benutzer keine Berechtigung hat, sich mit einer Datenbank zu
verbinden.
@item
Wenn ein Benutzer ein falsches Passwort angegeben hat.
@item
Wenn es länger als @code{connect_timeout} Sekunden dauert, um ein
Verbindungspaket zu erhalten.
@end itemize

Beachten Sie, dass obiges auch anzeigen könnte, dass jemand versucht, in
Ihre Datenbank einzubrechen!

@xref{SHOW VARIABLES}.

Andere Gründe für Probleme mit abgebrochenen Clients / abgebrochenen
Verbindungen:
@itemize @bullet
@item
Benutzung des Duplex-Ethernet-Protokolls, sowohl Halb- als auch
Voll-Duplex, unter Linux. Viele Linux-Ethernet-Treiber haben diesen Bug.
Sie können auf diesen Bug überprüfen, indem Sie eine sehr große Datei via
FTP zwischen diesen beiden Maschinen übertragen. Wenn ein Transfer nach dem
Schema schnelle Übertragung - Pause - schnelle Übertragung - Pause läuft,
haben Sie ein Linux-Duplex-Syndrom. Die einzige Lösung besteht darin, Halb-
und Vollduplex auf Hubs und Switches auszuschalten.
@item
Probleme mit der Thread-Bibliothek, was Unterbrechungen bei Lesevorgängen
verursacht.
@item
Schlecht konfiguriertes TCP/IP.
@item
Fehlerhafte Ethernets, Hubs, Switches, Kabel usw. Das kann nur durch
Austausch von Hardware sauber diagnostiziert werden.
@item
@code{max_allowed_packet} ist zu klein oder Anfragen erfordern mehr
Speicher, als Sie für @code{mysqld} zugewiesen haben.
@c German FIX unwrapped @xref
@xref{Packet too large}.
@end itemize


@node Full table, Cannot create, Communication errors, Common errors
@c German node Tabelle voll
@appendixsubsec @code{The table is full}-Fehler

@cindex Tabelle ist voll

Der Fehler tritt in älteren MySQL-Versionen auf, wenn eine
Hauptspeicher-basierende temporäre Tabelle größer als
@code{tmp_table_size} Bytes wird. Um dieses Problem zu vermeiden, können
Sie die @code{-O tmp_table_size=#}-Option für @code{mysqld} benutzen, um
die Größe der temporären Tabelle zu erhöhen, oder die SQL-Option
@code{SQL_BIG_TABLES} verwenden, bevor Sie die problematische Anfrage
abschicken. @xref{SET OPTION, , @code{SET OPTION}}.

Sie können auch @code{mysqld} mit der @code{--big-tables}-Option starten.
Das ist genau dasselbe, wie @code{SQL_BIG_TABLES} für alle Anfragen zu
benutzen.

In MySQL-Version 3.23 werden Hauptspeicher-basierende temporäre Tabellen
automatisch in Festplatten-basierende @code{MyISAM}-Tabellen umgewandelt,
wenn die Tabelle größer als @code{tmp_table_size} wird.


@node Cannot create, Commands out of sync, Full table, Common errors
@c German node Kann nicht erzeugen
@appendixsubsec @code{Can't create/write to file}-Fehler

@cindex can't create/write to file

Wenn Sie für einige Anfragen Fehler folgenden Typs erhalten:

@example
Can't create/write to file '\\sqla3fe_0.ism'.
@end example

Bedeutet das, dass MySQL keine temporäre Datei für die Ergebnismenge im
angegebenen temporären Verzeichnis erzeugen kann. (Der obige Fehler ist
eine typische Fehlermeldung unter Windows; die Unix-Fehlermeldung ist
ähnlich.) Das Problem läßt sich beheben, indem Sie @code{mysqld} mit
@code{--tmpdir=pfad} starten oder folgendes in Ihrer Optionsdatei ergänzen:

@example
[mysqld]
tmpdir=C:/temp
@end example

Unter der Annahme, dass das @file{c:\\temp}-Verzeichnis existiert.
@xref{Option files}.

Überprüfen Sie auch den Fehler-Code, den Sie bei @code{perror} erhalten.
Ein Grund kann ein Fehler wegen fehlenden Festplattenspeichers sein:

@example
shell> perror 28
Error code  28:  No space left on device
@end example


@node Commands out of sync, Ignoring user, Cannot create, Common errors
@c German node Befehl nicht synchronisiert
@appendixsubsec @code{Command out of sync}-Fehler in Client

@cindex Befehle nicht synchronisiert

Wenn Sie den Fehler @code{command out of sync; You can't run this command
now} in Ihrem Client-Code erhalten, rufen Sie Client-Funktionen in der
falschen Reihenfolge auf!

Das kann zum Beispiel passieren, wenn Sie @code{mysql_use_result()}
benutzen und versuchen, eine neue Anfrage auszuführen, bevor Sie
@code{mysql_free_result()} aufgerufen haben. Der Fehler passiert ebenfalls,
wenn Sie versuchen, zwei Anfragen auszuführen, die Daten zurückgeben, ohne
zwischendrin @code{mysql_use_result()} oder @code{mysql_store_result()}
aufzurufen.


@node Ignoring user, Cannot find table, Commands out of sync, Common errors
@c German node Benutzer ignoriert
@appendixsubsec @code{User ignored}-Fehler

Wenn Sie folgenden Fehler erhalten:

@code{Found wrong password for user: 'benutzer@@ein_host'; User ignored}

Bedeutet das, dass @code{mysqld} beim Start oder nach dem Neuladen der
Berechtigungstabellen einen Eintrag in der @code{user}-Tabelle mit einem
ungültigen Passwort gefunden hat. Als Ergebnis wird der Eintrag vom
Berechtigungssystem einfach ignoriert.

Mögliche Gründe und Problembehebung:

@itemize @bullet
@item
Sie lassen eine neue Version von @code{mysqld} mit einer alten
@code{user}-Tabelle laufen. Das können Sie prüfen, indem Sie
@code{mysqlshow mysql user} eingeben, um zu sehen, ob das Passwortfeld
kürzer als 16 Zeichen ist. Wenn das der Fall ist, können Sie diesen Zustand
beheben, indem Sie das @code{scripts/add_long_password}-Skript laufen
lassen.

@item
Der Benutzer hat ein altes Passwort (8 Zeichen lang) und Sie haben
@code{mysqld} nicht mit der @code{--old-protocol}-Option gestartet.

@item
@findex PASSWORD()
Sie haben in der @code{user}-Tabelle ein Passwort eingegeben, ohne die
@code{PASSWORD()}-Funktion zu benutzen. Benutzen Sie @code{mysql}, um den
Benutzer in der @code{user}-Tabelle mit einem neuen Passwort zu
aktualisieren. Stellen Sie sicher, dass Sie die @code{PASSWORD()}-Funktion
benutzen:

@example
mysql> update user set password=PASSWORD('ihr_passwort')
           where user='XXX';
@end example
@end itemize


@node Cannot find table, Cannot initialize character set, Ignoring user, Common errors
@c German node Tabelle nicht gefunden
@appendixsubsec @code{Table 'xxx' doesn't exist}-Fehler

Wenn Sie den Fehler @code{Table 'xxx' doesn't exist} oder @code{Can't find
file: 'xxx' (errno: 2)} erhalten, bedeutet das, dass in der aktuellen
Datenbank keine Tabelle mit dem Namen @code{xxx} existiert.

Beachten Sie, dass Datenbank- und Tabellennamen @strong{abhängig von der
verwendeten Groß-/Kleinschreibung} sind, weil MySQL Verzeichnisse und
Dateien benutzt, um Datenbanken und Tabellen zu speichern! (Unter Windows
sind Datenbank- und Tabellennamen unabhängig von der Schreibweise, aber
alle Verweise auf eine gegebene Tabelle innerhalb einer Anfrage müssen
dieselbe Schreibweise benutzen!)

Sie finden heraus, welche Tabellen sich in der aktuellen Datenbank
befinden, indem Sie @code{SHOW TABLES} eingeben. @xref{SHOW, ,
@code{SHOW}}.


@node Cannot initialize character set, Not enough file handles, Cannot find table, Common errors
@c German node Zeichensatz kann nicht initialisiert werden
@appendixsubsec @code{Can@'t initialize charset xxx}-Fehler.

@cindex Multibyte-Zeichensätze

Wenn Sie folgenden Fehler erhalten:

@example
MySQL Connection Failed: Can't initialize charset xxx
@end example

Bedeutet das eins der folgenden Dinge:

@itemize @bullet
@item
Der Zeichensatz ist ein Multi-Byte-Zeichensatz und Ihr Client unterstützt
diesen Zeichensatz nicht.

In diesem Fall müssen Sie Ihren Client neu kompilieren und die
@code{--with-charset=xxx}- oder die @code{--with-extra-charsets=xxx}-Option
angeben. @xref{configure options}.

Alle Standard-MySQL-Binärdistributionen werden mit
@code{--with-extra-character-sets=complex} kompiliert, was die
Unterstützung für alle Multi-Byte-Zeichensätze aktiviert.
@xref{Character sets}.

@item
Der Zeichensatz ist ein einfacher Zeichensatz, der nicht in @code{mysqld}
kompiliert wurde, und die Zeichensatz-Definitionsdateien sind nicht an der
Stelle, an der der Client sie erwartet.

In diesem Fall müssen Sie:

@itemize @bullet
@item
Den Client mit Unterstützung für den Zeichensatz neu kompilieren.
@xref{configure options}.
@item
Dem Client angeben, wo die Zeichensatz-Definitionsdateien sind. Bei vielen
Clients können Sie das mit der
@code{--character-sets-dir=pfad-to-charset-dir}-Option machen.
@item
Die Zeichensatz-Definitionsdatei in den Pfad kopieren, wo der Client sie zu
finden erwartet.
@end itemize
@end itemize


@node Not enough file handles,  , Cannot initialize character set, Common errors
@c German node Nicht genug Datei-Handles
@appendixsubsec File Not Found

Wenn Sie den Fehler @code{ERROR '...' not found (errno: 23)}, @code{Can't
open file: ... (errno: 24)} oder irgend einen anderen Fehler mit
@code{errno 23} oder @code{errno 24} erhalten, bedeutet das, dass Sie MySQL
nicht genug Datei-Deskriptoren zugewiesen haben. Sie können das
@code{perror}-Dienstprogramm benutzen, um eine Beschreibung dessen zu
erhalten, was die Fehlernummer bedeutet:

@example
shell> perror 23
File table overflow
shell> perror 24
Too many open files
shell> perror 11
Resource temporarily unavailable
@end example

Das Problem hierbei ist, dass @code{mysqld} versucht, zu viele Dateien
gleichzeitig offen zu halten. Sie können entweder @code{mysqld}
veranlassen, nicht so viele Dateien auf einmal zu öffnen, oder die Anzahl
von Datei-Deskriptoren heraufsetzen, über die @code{mysqld} verfügen kann.

Um @code{mysqld} anzuweisen, weniger Dateien zugleich offen zu halten,
können Sie den Tabellen-Cache kleiner machen, indem Sie die @code{-O
table_cache=32}-Option für @code{safe_mysqld} benutzen (der Vorgabewert ist
64). Wenn Sie den Wert von @code{max_connections} verringern, reduziert
auch das die Anzahl offener Dateien (der Vorgabewert ist 90).

@tindex ulimit
Um die Anzahl von Datei-Deskriptoren, die @code{mysqld} zur Verfügung
stehen, zu ändern, können Sie die @code{--open-files-limit=#}-Option für
@code{safe_mysqld} oder die @code{-O open-files-limit=#}-Option für
@code{mysqld} benutzen. @xref{SHOW VARIABLES}. Die einfachste Art, das zu
tun, besteht darin, eine Option zu Ihrer Optionsdatei hinzuzufügen.
@xref{Option files}. Wenn Sie eine alte @code{mysqld}-Version haben, die
das nicht unterstützt, können Sie das @code{safe_mysqld}-Skript editieren.
Es gibt dort eine auskommentierte Zeile @code{ulimit -n 256}. Entfernen Sie
das @code{'#'}-Zeichen, um diese Zeile zu aktivieren, und ändern Sie die
Anzahl 256, um die Anzahl verfügbarer Datei-Deskriptoren zu beeinflussen.

Mit @code{ulimit} (und @code{open-files-limit}) kann man die Anzahl von
Datei-Deskriptoren heraufsetzen, aber nur bis zu der Grenze, die das
Betriebssystem vorgibt. Darüber hinaus gibt es eine 'harte' Grenze, die nur
überschrieben werden kann, wenn Sie @code{safe_mysqld} oder @code{mysqld}
als Root starten (denken Sie daran, dass Sie in diesem Fall auch die
@code{--user=..}-Option benutzen müssen). Wenn Sie die
Betriebssystem-Grenze hinsichtlich der Anzahl von Datei-Deskriptoren, die
für jeden Prozess verfügbar sind, heraufsetzen müssen, schauen Sie in der
Dokumentation Ihres Betriebssystems nach.

Beachten Sie, dass @code{ulimit} nicht funktioniert, wenn Sie die
@code{tcsh}-Shell laufen lassen! @code{tcsh} berichtet auch nicht korrekte
Werte, wenn Sie die aktuellen Grenzen abfragen! In diesem Fall sollten Sie
@code{safe_mysqld} mit @code{sh} starten!


@node Installation Issues, Administration Issues, Common errors, Problems
@c German node Installationsprobleme
@appendixsec Installationsbezogene Themen



@menu
* Link errors::                 
* Changing MySQL user::         
* File permissions ::           
@end menu

@node Link errors, Changing MySQL user, Installation Issues, Installation Issues
@c German node Link-Fehler
@appendixsubsec Probleme beim Linken mit der MySQL-Client-Bibliothek

@cindex linken, Fehler
@cindex Fehler, linken
@cindex Probleme, linken

Wenn Sie Ihr Programm linken und Fehler für unreferenzierte Symbole
erhalten, die mit @code{mysql_} beginnen, wie folgende:

@example
/tmp/ccFKsdPa.o: In function `main':
/tmp/ccFKsdPa.o(.text+0xb): undefined reference to `mysql_init'
/tmp/ccFKsdPa.o(.text+0x31): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x57): undefined reference to `mysql_real_connect'
/tmp/ccFKsdPa.o(.text+0x69): undefined reference to `mysql_error'
/tmp/ccFKsdPa.o(.text+0x9a): undefined reference to `mysql_close'
@end example

Sollten Sie das durch Hinzufügen von
@code{-Lpath-to-the-mysql-library-lmysqlclient} als @strong{LETZTES} in
Ihrer Link-Zeile beheben können.

Wenn Sie @code{undefined reference}-Fehler bei der @code{uncompress}- oder
@code{compress}-Funktion erhalten, fügen Sie @code{-lz} als
@strong{LETZTES} zu Ihrer Link-Zeile hinzu und versuchen Sie es noch
einmal!

Wenn Sie @code{undefined reference}-Fehler bei Funktionen erhalten, die es
auf Ihrem System geben sollte, wie @code{connect}, sehen Sie in der
Handbuch-Seite (ManPage) für die fragliche Funktion nach, welche
Bibliotheken Sie zur Link-Zeile hinzufügen sollten!

Wenn Sie @code{undefined reference}-Fehler bei Funktionen erhalten, die es
auf Ihrem System nicht gibt, wie folgenden:

@example
mf_format.o(.text+0x201): undefined reference to `__lxstat'
@end example

Heißt das üblicherweise, dass Ihre Bibliothek auf einem System kompiliert
wurde, das nicht 100% kompatibel zu Ihrem System ist. In diesem Fall
sollten Sie die letzte MySQL-Quelldistribution herunter laden und sie
selbst kompilieren. @xref{Installing source}.

Wenn Sie versuchen, ein Programm laufen zu lassen und Fehler für
unreferenzierte Symbole erhalten, die mit @code{mysql_} anfangen, oder den
Fehler, dass die @code{mysqlclient}-Bibliothek nicht gefunden werden kann,
heißt das, dass Ihr System die gemeinsam genutzte
@code{libmysqlclient.so}-Bibliothek nicht findet.

Das Problem beheben Sie, indem Sie Ihr System anweisen, dort nach gemeinsam
genutzten Bibliotheken zu suchen, wo sich die Bibliothek befindet, mit
einer der folgenden Methoden:

@itemize @bullet
@item
Fügen Sie den Pfad zum Verzeichnis, in dem Sie @code{libmysqlclient.so}
haben, der @code{LD_LIBRARY_PATH}-Umgebungsvariablen hinzu.
@item
Fügen Sie den Pfad zum Verzeichnis, in dem Sie @code{libmysqlclient.so}
haben, der @code{LD_LIBRARY}-Umgebungsvariablen hinzu.
@item
Kopieren Sie @code{libmysqlclient.so} an eine Stelle, die von Ihrem System
durchsucht wird, wie @file{/lib}, und aktualisieren Sie die Informationen
über gemeinsam genutzte Bibliotheken, indem Sie @code{ldconfig} ausführen.
@end itemize

Eine weitere Möglichkeit, dieses Problem zu lösen, besteht darin, Ihr
Programm statisch mit @code{-static} zu linken oder die dynamischen
MySQL-Bibliotheken zu entfernen, bevor Sie Ihren Code linken. Im letzteren
Fall sollten Sie sicherstellen, dass keine anderen Programme die
dynamischen Bibliotheken benutzen!


@node Changing MySQL user, File permissions , Link errors, Installation Issues
@c German node Änderung des MySQL-Benutzers
@appendixsubsec Wie man MySQL als normaler Benutzer laufen läßt

@cindex starten, @code{mysqld}
@cindex @code{mysqld}, starten

Der MySQL-Server @code{mysqld} kann von jedem beliebigen Benutzer gestartet
werden und unter diesem laufen. Damit @code{mysqld} als Unix-Benutzer
@code{benutzername} läuft, müssen Sie folgendes tun:

@enumerate
@item
Halten Sie den Server an, falls er läuft (benutzen Sie @code{mysqladmin
shutdown}).

@item
Ändern Sie die Datenbankverzeichnisse und Dateien so, dass
@code{benutzername} die Berechtigungen zum Lesen und Schreiben von Dateien
darin hat (das müssen Sie eventuell als Unix-@code{root}-Benutzer machen):

@example
shell> chown -R benutzername /pfad/zu/mysql/datadir
@end example

Wenn Verzeichnisse oder Dateien im MySQL-Daten-Verzeichnis symbolische
Links sind, müssen Sie auch diesen Verknüpfungen folgen und die
Verzeichnisse und Dateien, auf die sie zeigen, ändern. @code{chown -R} kann
SymLinks für Sie folgen.

@item
Starten Sie den Server als Benutzer @code{benutzername} oder, wenn Sie
MySQL-Version 3.22 oder später benutzen, starten Sie @code{mysqld} als
Unix-@code{root}-Benutzer und benutzen Sie die
@code{--user=benutzername}-Option. @code{mysqld} schaltet um und läuft dann
unter Unix-Benutzer @code{benutzername}, bevor er irgend welche
Verbindungen annimmt.

@item
Um den Server automatisch beim Hochfahren des Systems unter dem angegebenen
Benutzernamen zu starten, fügen Sie zur @code{[mysqld]}-Gruppe der
@file{/etc/my.cnf}-Optionendatei oder der @file{my.cnf}-Optionendatei im
Datenverzeichnis des Servers eine @code{user}-Zeile hinzu, die den
Benutzernamen angibt. Beispiel:

@example
[mysqld]
user=benutzername
@end example
@end enumerate

Nunmehr sollte Ihr @code{mysqld}-Prozess korrekt unter dem Unix-Benutzer
@code{benutzername} laufen. Dennoch hat sich eins nicht geändert: Die
Inhalte der Berechtigungstabellen. Vorgabemäßig (direkt nach dem
Laufenlassen des Skripts @code{mysql_install_db}, das die
Berechtigungstabellen installiert), ist der MySQL-Benutzer @code{root} der
einzige Benutzer mit Zugriffsrechten auf die @code{mysql}-Datenbank. Er ist
auch der einzige, der Datenbanken erzeugen und löschen kann. Wenn Sie diese
Berechtigungen nicht geändert haben, sind sie noch gültig. Das sollte Sie
nicht davon abhalten, auf MySQL als der MySQL-@code{root}-Benutzer
zuzugreifen, wenn Sie als ein anderer Unix-Benutzer als @code{root}
eingeloggt sind. Geben Sie einfach für Client-Programme die @code{-u
root}-Option an.

Beachten Sie, dass der Zugriff auf MySQL als @code{root} (indem Sie
@code{-u root} auf der Kommandozeile eingeben) @emph{nichts} damit zu tun
hat, dass Sie MySQL als Unix-@code{root}-Benutzer laufen lassen oder als
irgend ein anderer Unix-Benutzer. Die Zugriffsberechtigungen und
Benutzernamen von MySQL sind komplett unterschiedlich von den
Unix-Benutzernamen. Die einzige Verbindung mit Unix-Benutzernamen besteht
darin, dass ein Client versuchen wird, sich mit Ihrem Unix-Login-Namen als
MySQL-Benutzernamen zu verbinden, wenn Sie beim Aufruf eines
Client-Programms keine @code{-u}-Option angeben.

Wenn Ihre Unix-Box selbst nicht abgesichert ist, sollten Sie zumindest ein
Passwort für den MySQL-@code{root}-Benutzer in den Berechtigungstabellen
angeben. Ansonsten kann jeder beliebige Benutzer mit einem Konto auf der
Maschine @code{mysql -u root datenbank} eingeben und tun, was er will.


@node File permissions,  , Changing MySQL user, Installation Issues
@c German node Dateirechte 
@appendixsubsec Probleme mit Dateirechten

@cindex Dateien, Rechte
@cindex Fehlermeldungen, can't find file
@cindex Dateien, Nachricht not found

Wenn Sie Probleme mit Dateirechten haben, wenn @code{mysql} zum Beispiel
folgende Fehlermeldung beim Erzeugen einer Tabelle ausgibt:

@example
Error: Can't find file: 'pfad/mit/dateiname.frm' (Errcode: 13)
@end example

@tindex UMASK-Umgebungsvariable
@tindex Umgebungsvariable, UMASK
Kann es sein, dass die Umgebungsvariable @code{UMASK} falsch gesetzt ist,
wenn @code{mysqld} startet. Der vorgabemäßige umask-Wert ist @code{0660}.
Sie können dieses Verhalten ändern, indem Sie @code{safe_mysqld} wie folgt
starten:

@example
shell> UMASK=384  # = 600 in oktal
shell> export UMASK
shell> /pfad/zu/safe_mysqld &
@end example

@tindex UMASK_DIR-Umgebungsvariable
@tindex Umgebungsvariable, UMASK_DIR
Vorgabemäßig erzeugt MySQL Datenbank- und @code{RAID}-Verzeichnisse mit
dem Berechtigungstyp 0700. Dieses Verhalten können Sie durch Setzen der
@code{UMASK_DIR}-Variablen ändern. Wenn Sie diese setzen, werden neue
Verzeichnisse mit kombiniertem @code{UMASK} und @code{UMASK_DIR} erzeugt.
Wenn Sie zum Beispiel Gruppenzugriff auf alle neuen Verzeichnisse geben
wollen, können Sie folgendes tun:

@example
shell> UMASK_DIR=504  # = 770 in oktal
shell> export UMASK_DIR
shell> /pfad/zu/safe_mysqld &
@end example

Ab MySQL-Version 3.23.25 nimmt MySQL an, dass die Werte für @code{UMASK}
und @code{UMASK_DIR} in oktal angegeben sind, wenn sie mit einer 0
anfangen.

@xref{Environment variables}.


@node Administration Issues, Query Issues, Installation Issues, Problems
@c German node Administrationsprobleme
@appendixsec Administrationsbezogene Themen



@menu
* Crashing::                    
* Resetting permissions::       
* Full disk::                   
* Temporary files::             
* Problems with mysql.sock::    
* Timezone problems::           
@end menu

@node Crashing, Resetting permissions, Administration Issues, Administration Issues
@c German node Abstürze
@appendixsubsec Was zu tun ist, wenn MySQL andauernd abstürzt

@cindex Absturz, wiederholter

Alle MySQL-Versionen werden auf vielen Plattformen getestet, bevor sie
herausgegeben werden. Das heißt nicht, dass es keinerlei Bugs in MySQL
gibt, aber es heißt, dass, wenn es Bugs gibt, diese sehr wenige und schwer
zu finden sind. Wenn Sie ein Problem haben, ist es immer hilfreich
herauszufinden, was Ihr System zum Absturz bringt, weil Sie dann viel
bessere Chancen haben, es schnell zu beheben.

Zunächst sollten Sie versuchen herauszufinden, ob das Problem darin
besteht, dass Ihr @code{mysqld}-Daemon stirbt, oder ob Sie ein Problem mit
Ihrem Client haben. Sie können herausfinden, seit wann Ihr
@code{mysqld}-Server hochgefahren ist, indem Sie @code{mysqladmin version}
ausführen. Wenn @code{mysqld} gestorben ist, finden Sie den Grund hierfür
womöglich in der Datei @file{mysql-daten-verzeichnis/`hostname`.err}.
@xref{Error log}.

Viele Abstürze von MySQL werden durch beschädigte Index- oder Daten-Dateien
verursacht. MySQL aktualisiert die Daten auf Platte mit dem @code{write()}
Systemaufruf, nach jedem SQL-Statement und bevor der Client über das
Ergebnis unterrichtet wird. (Das gilt nicht, wenn Sie mit
@code{delayed_key_writes} fahren, denn in diesem Fall werden nur die Daten
geschrieben.) Das bedeutet, dass die Daten sicher sind, selbst wenn
@code{mysqld} abstürzt, weil das Betriebssystem sicherstellt, dass die
nicht von MySQL zurückgeschriebenen Daten (flush) auf Platte
zurückgeschrieben werden. Sie können MySQL zwingen, alles nach jedem
SQL-Befehl auf Platte zurückzusynchronisieren,  indem Sie @code{mysqld} mit
@code{--flush} starten.

Das Gesagte bedeutet, dass Sie normalerweise keine beschädigten Tabellen
erhalten sollten, ausser in folgenden Fällen:

@itemize @bullet
@item
Jemand oder etwas killte @code{mysqld} oder die Maschine mitten während
einer Aktualisierung.
@item
Sie haben einen Bug in @code{mysqld} gefunden, der dazu führte, dass er
mitten während einer Aktualisierung starb.
@item
Jemand manipuliert die Daten- / Index-Dateien ausserhalb von
@strong{mysqld}, ohne die Tabelle korrekt zu sperren.
@item
Wenn Sie viele @code{mysqld}-Server auf denselben Daten auf einem System
laufen lassen, das Dateisystem-Sperren nicht gut unterstützt (das wird
normalerweise vom @code{lockd}-Daemon gehandhabt) oder wenn Sie mehrere
Server mit @code{--skip-locking} fahren.
@item
Wenn Sie eine beschädigte Index- / Daten-Datei haben, die sehr falsche
Daten enthält, die @code{mysqld} durcheinander brachten.
@item
Sie haben einen Bug im Datenspeicher-Code gefunden. Das ist nicht sehr
wahrscheinlich, aber zumindest möglich. In diesem Fall können Sie
versuchen, den Dateityp auf einen anderen Datenbank-Handler umzustellen,
indem Sie @code{ALTER TABLE} auf eine reparierte Kopie der Tabelle
anwenden!
@end itemize

Weil es sehr schwierig ist herauszufinden, warum etwas abstürzt, versuchen
Sie zuerst herauszufinden, ob Dinge, die bei anderen funktionieren, bei
Ihnen abstürzen, oder ob das nicht der Fall ist. Versuchen Sie bitte
folgendes:

@itemize @bullet
@item
Fahren Sie den @code{mysqld}-Daemon mit @code{mysqladmin shutdown} herunter
und führen Sie @code{myisamchk --silent --force */*.MYI} auf alle Tabellen
aus. Starten Sie den @code{mysqld}-Daemon erneut. Das stellt sicher, dass
Sie von einem sauberen Ausgangszustand aus fahren.
@xref{MySQL Database Administration}.

@item
Benutzen Sie @code{mysqld --log} und versuchen Sie den Informationen im Log
zu entnehmen, ob eine bestimmte Anfrage den Server killt oder nicht. Etwa
95% aller Bugs beziehen sich auf eine bestimmte Anfrage! Normalerweise ist
das eine der letzten Anfragen in der Log-Datei, direkt bevor MySQL neu
startete. @xref{Query log}. Wenn Sie MySQL wiederholt mit einer
der Anfragen killen, selbst wenn Sie alle Tabellen direkt vor der
Ausführung der Anfrage überprüft haben, haben Sie den Bug eingegrenzt und
sollten dafür einen Bug-Bericht schreiben! @xref{Bug reports}.

@item
Versuchen Sie, einen Testfall herzustellen, den wir zur Reproduzierung des
Problems verwenden können. @xref{Reproduceable test case}.

@item
Versuchen Sie, die beigefügten mysql-test test und MySQL-Benchmarks laufen
zu lassen. @xref{MySQL-Test-Suite}. Sie können MySQL recht gut prüfen. Sie
können den Benchmarks auch selbst Code hinzufügen, der Ihre Applikation
simuliert! Die Benchmarks finden sich im @file{bench}-Verzeichnis in der
Quelldistribution oder bei einer Binärdistribution im
@file{sql-bench}-Verzeichnis unter Ihrem MySQL-Installationsverzeichnis.

@item
Probieren Sie @code{fork_test.pl} und @code{fork2_test.pl}.

@item
Wenn Sie MySQL zum Debuggen konfigurieren, ist es wesentlich einfacher,
Informationen über mögliche Fehler zu erhalten, wenn etwas schief geht.
Konfigurieren Sie MySQL mit der @code{--with-debug}-Option oder mit der
@code{--with-debug=full}-Option für @code{configure} neu und kompilieren
Sie neu. @xref{Debugging server}.

@item
Wenn MySQL zum Debuggen konfiguriert wird, wird ein sicherer
Speicher-Zuweiser (Memory Allocator) hinzugefügt, der einige Fehler finden
kann. Ausserdem erfolgen etliche Ausgaben über das, was gerade geschieht.

@item
Haben Sie die neuesten Patches für Ihr Betriebssystem installiert?

@item
Benutzen Sie die @code{--skip-locking}-Option für @code{mysqld}. Auf
manchen Systemen arbeitet der @code{lockd}-Sperrmanager nicht korrekt. Die
@code{--skip-locking}-Option weist @code{mysqld} an, keine externen Sperren
zu benutzen. (Das heißt, dass Sie nicht zwei @code{mysqld}-Server auf
denselben Daten laufen lassen können und dass Sie vorsichtig sein müssen,
wenn Sie @code{myisamchk} benutzen, aber es kann aufschlussreich sein, die
Option testweise zu benutzen.)

@item
Haben Sie @code{mysqladmin -u root processlist} ausprobiert, wenn
@code{mysqld} zu laufen scheint, aber nicht antwortet? Manchmal ist
@code{mysqld} nicht komatös, obwohl es so aussieht. Das Problem kann darin
bestehen, dass alle Verbindungen in Benutzung sind, oder es kann ein
internes Sperrproblem vorliegen. @code{mysqladmin processlist} ist
üblicherweise in der Lage, in solchen Fällen eine Verbindung aufzubauen und
kann nützliche Informationen über die momentane Anzahl von Verbindungen und
ihren Status liefern.

@item
Lassen Sie den Befehl @code{mysqladmin -i 5 status} oder @code{mysqladmin
-i 5 -r status} in einem separaten Fenster laufen, um statistische
Informationen auszugeben, während Sie Ihre anderen Anfragen laufen lassen.

@item
Versuchen Sie folgendes:
@enumerate
@item
Starten Sie @code{mysqld} von @code{gdb} aus (oder in einem anderen
Debugger).
@xref{Using gdb on mysqld}.

@item
Lassen Sie Ihre Test-Skripts laufen.

@item
Geben Sie die Ablaufverfolgung (Backtrace) und die lokalen Variablen der
untersten 3 Ebenen aus. In gdb können Sie das mit folgenden Befehle tun,
wenn @code{mysqld} innerhalb von gdb abgestürzt ist:

@example
backtrace
info local
up
info local
up
info local
@end example

Mit gdb können Sie auch untersuchen, welchen Thread es gibt (mit @code{info
thread} und zu einem speziellen Thread umschalten (mit @code{thread #},
wobei @code{#} die Thread-Kennung ist).
@end enumerate

@item
Versuchen Sie, Ihre Applikation mit einem Perl-Skript zu simulieren, um
MySQL zu zwingen, abzustürzen oder fehlerhaftes Verhalten an den Tag zu
legen.

@item
Senden Sie einen normalen Bug-Bericht. @xref{Bug reports}. Geben Sie mehr
Details an als üblich. Weil MySQL bei vielen Leuten funktioniert, kann es
sein, dass der Absturz das Ergebnis von etwas ist, das nur auf Ihrem
Computer existiert (beispielsweise ein Fehler, der aus Ihren besonderen
Systembibliotheken resultiert).

@item
Wenn Sie ein Problem mit Tabellen haben, die Zeilen dynamischer Länge
enthalten, und Sie nicht @code{BLOB/TEXT}-Spalten benutzen (sondern nur
@code{VARCHAR}-Spalten), können Sie versuchen, alle @code{VARCHAR}- in
@code{CHAR}-Spalten umzuwandeln, indem Sie @code{ALTER TABLE} verwenden.
Das erzwingt, dass MySQL Zeilen fester Länge verwendet. Zeilen fester Länge
benötigen etwas mehr Platz, sind aber fehlertoleranter gegenüber
Beschädigungen!

Der aktuelle Code mit dynamischen Zeilen ist bei MySQL AB seit mindestens
drei Jahren ohne jedes Problem in Benutzung, aber naturgemäß sind Zeilen
dynamischer Länge fehleranfälliger. Daher kann es eine gute Idee sein, das
oben Gesagte auszuprobieren.
@end itemize


@node Resetting permissions, Full disk, Crashing, Administration Issues
@c German node Berechtigungen zurücksetzen
@appendixsubsec Wie ein vergessenes Passwort zurückgesetzt wird

@cindex Passwörter, vergessen
@cindex Passwörter, zurücksetzen
@cindex Root-Benutzer, Passwort zurücksetzen

Wenn Sie das @code{root}-Benutzerpasswort für MySQL vergessen haben, können
Sie es mit folgender Prozedur wiederherstellen:

@enumerate
@item
Fahren Sie den @code{mysqld}-Server durch Senden von @code{kill} (nicht
@code{kill -9}) an den @code{mysqld}-Server herunter. Die Prozess-Kennung
(PID) wird in einer @code{.pid}-Datei gespeichert, die sich normalerweise
im MySQL-Datenbank-Verzeichnis befindet:

@example
kill `cat /mysql-daten-verzeichnis/hostname.pid`
@end example

Hierfür müssen Sie entweder der Unix-@code{root}-Benutzer sein oder
derselbe Benutzer, unter dem der Server läuft.

@item
Starten Sie @code{mysqld} mit der @code{--skip-grant-tables}-Option neu.
@item
Verbinden Sie sich mit dem @code{mysqld}-Server mit @code{mysql -h hostname
mysql} und ändern Sie das Passwort mit einem @code{GRANT}-Befehl.
@xref{GRANT,,@code{GRANT}}. Sie können dasselbe auch mit @code{mysqladmin
-h hostname -u benutzer password 'neues_passwort'} machen.

@item
Laden Sie die Berechtigungstabellen neu mit @code{mysqladmin -h hostname
flush-privileges} oder mit dem SQL-Befehl @code{FLUSH PRIVILEGES}.
@end enumerate

Beachten Sie, dass nach dem Start von @code{mysqld} mit
@code{--skip-grant-tables} jede Benutzung von @code{GRANT}-Befehlen zu
einem @code{Unknown command}-Fehler führt, bis Sie @code{FLUSH PRIVILEGES}
ausgeführt haben.


@node Full disk, Temporary files, Resetting permissions, Administration Issues
@c German node Platte voll
@appendixsubsec Wie MySQL mit vollen Festplatten umgeht

@cindex volle Festplatte
@cindex Festplatte voll

@noindent
Wenn etwas hinsichtlich der Festplatte passiert, tut MySQL folgendes:

@itemize @bullet
@item
Er prüft einmal pro Minute, um festzustellen, ob es genug Platz gibt, um
die aktuelle Zeile zu schreiben oder nicht. Wenn genug Platz vorhanden ist,
wird fortgefahren, als sei nichts geschehen.
@item
Alle 6 Minuten schreibt er einen Eintrag in die Log-Datei mit einer Warnung
wegen voller Festplatte.
@end itemize

@noindent
Um das Problem abzumildern, können Sie folgende Aktionen unternehmen:

@itemize @bullet
@item
Um einfach weiterzumachen, müssen Sie lediglich genug Festplattenplatz
freigeben, damit alle Datensätze eingefügt werden können.
@item
Um den Thread abzubrechen, müssen Sie @code{mysqladmin kill} an den Thread
senden. Der Thread wird beim nächsten Mal, wenn er die Festplatte prüft (in
1 Minute) abgebrochen.
@item
Beachten Sie, dass eventuell ein anderer Thread auf die Tabelle wartet, die
den Zustand ``Platte voll'' verursachte. Wenn Sie mehrere ``gesperrte''
Threads haben, kann es sein, dass Sie einen Thread killen, der wegen
``Platte voll'' wartet, dass dafür aber ein anderer Thread weitermacht.
@end itemize

Ausnahmen zum obigen Verhalten treten bei der Benutzung von @code{REPAIR}
oder @code{OPTIMIZE} auf, oder wenn die Indexe nach einem @code{LOAD DATA
INFILE}- oder einem @code{ALTER TABLE}-Statement im Stapel erzeugt werden.

Alle obigen Befehle benutzen eventuell große temporäre Dateien, die - sich
selbst überlassen - für den Rest des Systems große Probleme verursachen
können. Wenn MySQL ein ``Platte voll'' erhält, während irgend eine der
obigen Operationen ausgeführt wird, entfernt er die großen temporären
Dateien und markiert die Tabelle als beschädigt (ausser bei @code{ALTER
TABLE}, wobei die alte Tabelle unverändert gelassen wird).


@node Temporary files, Problems with mysql.sock, Full disk, Administration Issues
@c German node Temporäre Dateien
@appendixsubsec Wohin MySQL temporäre Dateien speichert

MySQL benutzt den Wert der @code{TMPDIR}-Umgebungsvariablen als Pfadnamen
des Verzeichnisses, in dem temporäre Dateien gespeichert werden. Wenn Sie
@code{TMPDIR} nicht gesetzt haben, benutzt MySQL die System-Vorgabe, die
normalerweise @file{/tmp} oder @file{/usr/tmp} ist. Wenn das Dateisystem,
das Ihr Verzeichnis für temporäre Dateien enthält, zu klein ist, sollten
Sie @code{safe_mysqld} editieren, um @code{TMPDIR} so zu setzen, dass sie
auf ein Verzeichnis in einem Dateisystem zeigt, wo Sie genug Platz haben!
Sie können das temporäre Verzeichnis auch mit der @code{--tmpdir}-Option
für @code{mysqld} setzen.

MySQL erzeugt alle temporären Dateien als versteckte Dateien. Das stellt
sicher, dass die temporären Dateien entfernt werden, wenn @code{mysqld}
beendet wird. Der Nachteil versteckter Dateien ist, dass Sie eine große
temporäre Datei nicht sehen, die das Dateisystem auffüllt, in dem sich das
Verzeichnis für temporäre Dateien befindet.

Zum Sortieren (@code{ORDER BY} oder @code{GROUP BY}) benutzt MySQL
normalerweise ein oder zwei temporäre Dateien. Der maximal benötigte
Speicherplatz ist:

@example
(laenge_dessen_was_sortiert_wird + groesse_von(datenbank_zeiger)) *
anzahl_uebereinstimmender_zeilen * 2
@end example

@code{groesse_von(datenbank_zeiger)} ist üblicherweise 4, kann in Zukunft
aber für wirklich große Tabellen anwachsen.

Bei einigen @code{SELECT}-Anfragen erzeugt MySQL zusätzliche temporäre
SQL-Tabellen. Diese sind nicht versteckt und haben Namen der Form
@file{SQL_*}.

@code{ALTER TABLE} erzeugt eine temporäre Tabelle im selben Verzeichnis, in
dem sich die Original-Tabelle befindet.


@node Problems with mysql.sock, Timezone problems, Temporary files, Administration Issues
@c German node Probleme mit mysql.sock
@appendixsubsec Wie Sie die MySQL-Socket-Datei @file{/tmp/mysql.sock} schützen oder ändern

@cindex @code{mysql.sock}, schützen
@cindex löschen, @code{mysql.sock}

Wenn Sie Probleme damit haben, dass jeder beliebige den
MySQL-Kommunikations-Socket @file{/tmp/mysql.sock} löschen kann, können Sie
unter den meisten Versionen von Unix Ihr @file{/tmp}-Dateisystem schützen,
indem Sie darauf das @code{sticky} Bit setzen. Loggen Sie sich als
@code{root} ein und tun Sie folgendes:

@example
shell> chmod +t /tmp
@end example

Das schützt Ihr @file{/tmp}-Dateisystem, so dass Dateien nur von ihren
Besitzern oder dem Superuser (@code{root}) gelöscht werden können.

Sie können überprüfen, ob das @code{sticky} Bit gesetzt ist, indem Sie
@code{ls -ld /tmp} ausführen. Wenn das letzte Berechtigungsbit @code{t}
ist, ist das Bit gesetzt.

@cindex Speicherort des Sockets ändern

Sie können den Speicherort ändern, den MySQL benutzt, um die Socket-Datei
Socket-Datei abzulegen, indem Sie eine der folgenden Prozeduren ausführen:

@itemize @bullet
@item
Geben Sie den Pfad in einer globalen oder lokalen Optionsdatei an.
Beispielsweise können Sie in @code{/etc/my.cnf} eintragen:

@example
[client]
socket=pfad-fuer-socket-datei

[mysqld]
socket=pfad-fuer-socket-datei
@end example
@xref{Option files}.
@item
Geben Sie den Pfad auf der Kommandozeile für @code{safe_mysqld} und die
meisten Clients mit der @code{--socket=pfad-fuer-socket-datei}-Option an.
@item
Geben Sie den Pfad zum Socket in der
@code{MYSQL_UNIX_PORT}-Umgebungsvariablen an.
variable.
@item
Definieren Sie den Pfad mit der @code{configure}-Option
@code{--with-unix-socket-path=pfad-fuer-socket-datei}.
@xref{configure options}.
@end itemize

Mit folgendem Befehl können Sie testen, ob der Socket funktioniert:

@example
shell> mysqladmin --socket=/pfad/zu/socket version
@end example

@node Timezone problems,  , Problems with mysql.sock, Administration Issues
@c German node Zeitzonen-Probleme
@appendixsubsec Zeitzonen-Probleme

@cindex Zeitzonen-Probleme
@cindex Probleme, Zeitzone

@tindex TZ-Umgebungsvariable
@tindex Umgebungsvariable, TZ

Wenn es Probleme damit gibt, dass @code{SELECT NOW()} Werte in GMT
(Greenwich Mean Time) zurückgibt und nicht in Ihrer lokalen Zeit, müssen
Sie die @code{TZ}-Umgebungsvariable auf Ihre aktuelle Zeitzone setzen. Das
sollte für die Umgebung gemacht werden, in der der Server läuft, zum
Beispiel in @code{safe_mysqld} oder @code{mysql.server}.
@xref{Environment variables}.


@node Query Issues, Table Definition Issues, Administration Issues, Problems
@c German node Anfragenprobleme
@appendixsec Anfragenbezogene Themen



@menu
* Case sensitivity::            
* Using DATE::                  
* Problems with NULL::          
* Problems with alias::         
* Deleting from related tables::  
* No matching rows::            
@end menu

@node Case sensitivity, Using DATE, Query Issues, Query Issues
@c German node Groß-/Kleinschreibung
@appendixsubsec Groß-/Kleinschreibung beim Suchen

@cindex Groß-/Kleinschreibung, beim Suchen
@cindex Suchen und Groß-/Kleinschreibung
@cindex chinesisch
@cindex Big5, chinesische Zeichensatz-Kodierung

Vorgabemäßig sind MySQL-Suchen unabhängig von der verwendeten
Groß-/Kleinschreibung (obwohl es einige Zeichensätze gibt, die nie
unabhängig von der verwendeten Groß-/Kleinschreibung sind, wie
@code{tschechisch}). Wenn Sie daher mit @code{spalten_name LIKE 'a%'}
suchen, erhalten Sie alle Spaltenwerte, die mit @code{A} oder @code{a}
anfangen. Wenn Sie die Suche abhängig von der verwendeten
Groß-/Kleinschreibung machen wollen, verwenden Sie etwas wie
@code{INSTR(spalten_name, "A")=1}, um ein Präfix zu überprüfen, oder
benutzen Sie @code{STRCMP(spalten_name, "A") = 0}, wenn der Spaltenwert
exakt @code{"A"} sein muss.

Einfache Vergleichsoperationen (@code{>=, >, = , < , <=}, Sortieren und
Gruppieren) basieren auf dem ``Sortierwert'' jedes Zeichens. Buchstaben mit
demselben Sortierwert (wie E, e und é) werden als dasselbe Zeichen
behandelt!

In älteren MySQL-Versionen wurden @code{LIKE}-Vergleiche mit dem
Großschreibungswert jedes Zeichens durchgeführt (E == e, aber E <> é). In
neueren MySQL-Versionen funktioniert @code{LIKE} genau wie die anderen
Vergleichsoperatoren.

Wenn Sie wollen, dass eine Spalte immer abhängig von der verwendeten
Groß-/Kleinschreibung behandelt wird, deklarieren Sie sie als
@code{BINARY}. @xref{CREATE TABLE, , @code{CREATE TABLE}}.

Wenn Sie chinesische Daten in der so genannten Big5-Kodierung verwenden,
sollten Sie alle Zeichenspalten @code{BINARY} machen. Das funktioniert,
weil die Sortierreihenfolge von Big5-Zeichen auf der Reihenfolge von
ASCII-Codes basiert.


@node Using DATE, Problems with NULL, Case sensitivity, Query Issues
@c German node Benutzung von DATE
@appendixsubsec Probleme bei der Benutzung von @code{DATE}-Spalten

@findex DATE

@cindex DATE-Spalten, Probleme
@cindex Probleme, @code{DATE}-Spalten

Das Format eines @code{DATE}-Werts ist @code{'YYYY-MM-DD'}. Gemäß ANSI-SQL
ist kein anderes Format zulässig. Sie sollten dieses Format in
@code{UPDATE}-Ausdrücken und in der WHERE-Klausel von
@code{SELECT}-Statements benutzen. Beispiel:

@example
mysql> SELECT * FROM tabelle WHERE date >= '1997-05-05';
@end example

Aus Gründen der Annehmlichkeit konvertiert MySQL automatisch ein Datum in
eine Zahl, wenn das Datum in einem numerischen Zusammenhang benutzt wird
(und umgekehrt). MySQL unterstützt ausserdem ein ``entspanntes''
Zeichenkettenformat beim Aktualisieren und in einer @code{WHERE}-Klausel,
die ein Datum mit einer @code{TIMESTAMP}-, @code{DATE}- oder einer
@code{DATETIME}-Spalte vergleicht. (Entspannt heißt hierbei, dass jedes
beliebige Satzzeichen als Trennzeichen zwischen Bestandteilen benutzt
werden darf. Beispielsweise sind @code{'1998-08-15'} und
@code{'1998#08#15'} äquivalent.) MySQL kann auch eine Zeichenkette
umwandeln, die keine Trennzeichen enthält (wie @code{'19980815'}),
vorausgesetzt, dass diese als Datum einen Sinn ergibt.

Das spezielle Datum @code{'0000-00-00'} kann als @code{'0000-00-00'}
gespeichert und abgerufen werden. Wenn man ein @code{'0000-00-00'}-Datum
über @strong{MyODBC} benutzt, wird es automatisch in @code{NULL}
umgewandelt (@strong{MyODBC}-Version 2.50.12 und höher), weil ODBC diese
Art von Datum nicht handhaben kann.

Weil MySQL die oben genannten Umwandlungen durchführt, funktionieren
folgende Statements:

@example
mysql> INSERT INTO tabelle (idate) VALUES (19970505);
mysql> INSERT INTO tabelle (idate) VALUES ('19970505');
mysql> INSERT INTO tabelle (idate) VALUES ('97-05-05');
mysql> INSERT INTO tabelle (idate) VALUES ('1997.05.05');
mysql> INSERT INTO tabelle (idate) VALUES ('1997 05 05');
mysql> INSERT INTO tabelle (idate) VALUES ('0000-00-00');

mysql> SELECT idate FROM tabelle WHERE idate >= '1997-05-05';
mysql> SELECT idate FROM tabelle WHERE idate >= 19970505;
mysql> SELECT mod(idate,100) FROM tabelle WHERE idate >= 19970505;
mysql> SELECT idate FROM tabelle WHERE idate >= '19970505';
@end example

@noindent
Folgendes jedoch funktioniert nicht:

@example
mysql> SELECT idate FROM tabelle WHERE STRCMP(idate,'19970505')=0;
@end example

@code{STRCMP()} ist eine Zeichenkettenfunktion, daher wird @code{idate} in
eine Zeichenkette umgewandelt und ein Zeichenkettenvergleich durchgeführt.
MySQL wandelt @code{'19970505'} nicht in ein Datum um und führt einen
Datumsvergleich durch.

Beachten Sie, dass MySQL nicht prüft, ob ein Datum korrekt ist oder nicht.
Wenn Sie ein falsches Datum wie @code{'1998-2-31'} speichern, wird das
falsche Datum gespeichert. Wenn das Datum in keinen vernünftigen Wert
umgewandelt werden kann, wird @code{0} im @code{DATE}-Feld gespeichert. Das
ist hauptsächlich eine Sache der Geschwindigkeit, und wir sind der Meinung,
dass es Sache der Applikation und nicht des Servers ist, Datumsangaben zu
überprüfen.


@node Problems with NULL, Problems with alias, Using DATE, Query Issues
@c German node Probleme mit NULL
@appendixsubsec Probleme mit @code{NULL}-Werten

@cindex @code{NULL}-Werte im Vergleich mit leeren Werten

@tindex NULL

Das Konzept des @code{NULL}-Wert ist eine häufige Quelle der Verwirrung für
SQL-Anfänger. Diese denken häufig, @code{NULL} sei dasselbe wie eine leere
Zeichenkette @code{''}. Das ist nicht der Fall! So sind zum Beispiel
folgende Statements grundverschieden:

@example
mysql> INSERT INTO meine_tabelle (Telefon) VALUES (NULL);
mysql> INSERT INTO meine_tabelle (Telefon) VALUES ("");
@end example

Beide Statements fügen einen Wert in die @code{Telefon}-Spalte ein, aber
das erste fügt einen @code{NULL}-Wert und das zweite eine leere
Zeichenkette ein. Die Bedeutung des ersten ist etwa ``Telefonnummer
unbekannt'' und des zweiten ``Keine Telefonnummer''.

In SQL ist der @code{NULL}-Wert im Vergleich mit jedem anderen Wert immer
UNWAHR (false), selbst im Vergleich mit @code{NULL}. Ein Ausdruck, der
@code{NULL} enthält, erzeugt immer einen @code{NULL}-Wert, ausser wenn es
in der Dokumentation der Operatoren und Funktionen, die im Ausdruck
beteiligt sind, anders angegeben ist. Alle Spalten im folgenden Beispiel
geben @code{NULL} zurück:

@example
mysql> SELECT NULL,1+NULL,CONCAT('unsichtbar',NULL);
@end example

Wenn Sie nach Spaltenwerten suchen, die @code{NULL} sind, können Sie nicht
@code{=NULL} benutzen. Folgendes Statement gibt keine Zeilen zurück, weil
@code{ausdruck = NULL} für jeden beliebigen Ausdruck UNWAHR (false) ist:

@example
mysql> SELECT * FROM meine_tabelle WHERE Telefon = NULL;
@end example

Um nach @code{NULL}-Werten zu suchen, müssen Sie @code{IS NULL} benutzen.
Folgende Beispiele zeigen, wie Sie die @code{NULL}-Telefonnummer und die
leere Telefonnummer finden:

@example
mysql> SELECT * FROM meine_tabelle WHERE Telefon IS NULL;
mysql> SELECT * FROM meine_tabelle WHERE Telefon = "";
@end example

In MySQL können Sie - wie bei vielen anderen SQL-Servern - keine Spalten
indexieren, die @code{NULL}-Werte enthalten dürfen. Sie müssen solche
Spalten aus @code{NOT NULL} deklarieren. Sie dürfen in eine indexierte
Spalte keine @code{NULL}-Werte einfügen.

@findex LOAD DATA INFILE
Wenn Sie Daten mit @code{LOAD DATA INFILE} einlesen, werden leere Spalten
mit @code{''} aktualisiert. Wenn Sie einen @code{NULL}-Wert in einer Spalte
haben wollen, müssen Sie in der Textdatei @code{\N} benutzen. Unter manchen
Umständen kann auch das Literalwort @code{'NULL'} benutzt werden.
@xref{LOAD DATA, , @code{LOAD DATA}}.

Wenn Sie @code{ORDER BY} benutzen, werden @code{NULL}-Werte zuerst
angezeigt. Wenn Sie mit @code{DESC} in absteigender Reihenfolge sortieren,
werden @code{NULL}-Werte zuletzt angezeigt. Wenn Sie @code{GROUP BY}
benutzen, werden alle @code{NULL}-Werte als gleich betrachtet.

Um die Handhabung von @code{NULL} zu erleichtern, können Sie die @code{IS
NULL}- und @code{IS NOT NULL}-Operatoren und die @code{IFNULL()}-Funktion
benutzen.

@cindex @code{TIMESTAMP} und @code{NULL}-Werte
@cindex @code{AUTO_INCREMENT} und @code{NULL}-Werte
@cindex @code{NULL}-Werte und @code{TIMESTAMP}-Spalten
@cindex @code{NULL}-Werte und @code{AUTO_INCREMENT}-Spalten
Bei manchen Spaltentypen werden @code{NULL}-Werte besonders behandelt. Wenn
Sie @code{NULL} in die erste @code{TIMESTAMP}-Spalte einer Tabelle
einfügen, werden das aktuelle Datum und die aktuelle Zeit eingefügt. Wenn
Sie @code{NULL} in eine @code{AUTO_INCREMENT}-Spalte einfügen, wird die
nächste Zahl in der Zahlenfolge eingefügt.


@node Problems with alias, Deleting from related tables, Problems with NULL, Query Issues
@c German node Probleme mit alias
@appendixsubsec Probleme mit @code{alias}

@tindex alias

Sie können ein Alias verwenden, um auf eine Spalte im @code{GROUP BY}-,
@code{ORDER BY}- oder @code{HAVING}-Teil zu verweisen. Aliase können auch
verwendet werden, um Spalten bessere Namen zu geben:

@example
SELECT SQRT(a*b) as wurzel FROM tabelle GROUP BY wurzel HAVING wurzel > 0;
SELECT id,COUNT(*) AS zaehl FROM tabelle GROUP BY id HAVING zaehl > 0;
SELECT id AS "kunden-kennung" FROM tabelle;
@end example

Beachten Sie, dass ANSI-SQL verbietet, in einer @code{WHERE}-Klausel auf
ein Alias zu verweisen. Das liegt daran, dass der Spaltenwert
möglicherweise noch nicht feststeht, wenn der @code{WHERE}-Code ausgeführt
wird. Folgende Anfrage zum Beispiel ist @strong{unzulässig}:

@example
SELECT id,COUNT(*) AS zaehl FROM tabelle WHERE zaehl > 0 GROUP BY id;
@end example

Das @code{WHERE}-Statement wird ausgeführt, um festzulegen, welche Zeilen
im @code{GROUP BY}-Teil enthalten sein sollen, während @code{HAVING}
benutzt wird, um zu entscheiden, welche Zeilen der Ergebnismenge benutzt
werden sollten.


@node Deleting from related tables, No matching rows, Problems with alias, Query Issues
@c German node Löschen aus verwandten Tabellen
@appendixsubsec Zeilen aus verwandten Tabellen löschen

@cindex löschen, Zeilen
@cindex Zeilen, löschen
@cindex Tabellen, Zeilen löschen

Weil MySQL keine Sub-Selects oder die Benutzung von mehr als einer Tabelle
im @code{DELETE}-Statement unterstützt, müssen Sie folgenden Ansatz wählen,
um Zeilen aus zwei verwandten Tabellen zu löschen:

@enumerate
@item
Wählen (@code{SELECT}) Sie die Zeilen auf der Grundlage einer
@code{WHERE}-Bedingung in der Haupt-Tabelle aus.
@item
Löschen (@code{DELETE}) Sie die Zeilen in der Haupt-Tabelle auf der
Grundlage derselben Bedingung.
@item
Löschen Sie die Zeilen aus der verwandten Tabelle, bei denen die verwandte
Spalte in den ausgewählten Zeilen vorkommt (@code{DELETE FROM
verwandte_tabelle WHERE verwandte_spalte IN (ausgewaehlte_zeilen)}.
@end enumerate

Wenn die Gesamtzahl von Zeichen in der Anfrage mit @code{verwandte_spalte}
mehr als 1.048.576 beträgt (der Vorgabewert von @code{max_allowed_packet},
sollten Sie sie in kleinere Teile aufspalten und mehrfache
@code{DELETE}-Statements ausführen. Wahrscheinlich geht das Löschen
(@code{DELETE}) am Schnellsten, wenn Sie nur 100 bis 1000
@code{verwandte_spalte}-Kennungen pro Anfrage löschen, wenn
@code{verwandte_spalte} ein Index ist. Wenn @code{verwandte_spalte} kein
Index ist, ist die Geschwindigkeit unabhängig von der Anzahl von Argumenten
in der @code{IN}-Klausel.


@node No matching rows,  , Deleting from related tables, Query Issues
@c German node Keine übereinstimmenden Zeilen
@appendixsubsec Probleme bei keinen übereinstimmenden Zeilen lösen

@cindex keine übereinstimmenden Zeilen
@cindex Zeilen, Übereinstimmungsprobleme

Wenn Sie eine komplizierte Anfrage haben, die viele Tabellen hat und keine
Zeilen zurückgibt, sollten Sie folgende Prozedur benutzen, um
herauszufinden, was bei Ihrer Anfrage falsch ist:

@enumerate
@item
Testen Sie die Anfrage mit @code{EXPLAIN} und prüfen Sie, ob Sie etwas
finden können, das offensichtlich falsch ist. @xref{EXPLAIN, ,
@code{EXPLAIN}}.

@item
Wählen Sie in der @code{WHERE}-Klausel nur die Felder aus, die benutzt
werden.

@item
Entfernen Sie nacheinander Tabelle für Tabelle aus der Anfrage, bis sie
Zeilen zurückgibt. Wenn die Tabellen Groß sind, ist es eine gute Idee,
@code{LIMIT 10} bei der Anfrage zu benutzen.

@item
Machen Sie ein @code{SELECT} für die Spalte, die mit einer Zeile hätte
übereinstimmen sollen, gegen die Tabelle, die als letzte aus der Anfrage
entfernt wurde.

@item
Wenn Sie @code{FLOAT}- oder @code{DOUBLE}-Spalten mit Zahlen vergleichen,
die Dezimalstellen haben, können Sie nicht @code{=} benutzen! Das Problem
tritt in den meisten Computersprachen auf, weil Fließkommawerte keine
exakten Werte sind:

@example
mysql> SELECT * FROM tabelle WHERE float_spalte=3.5;
mysql> SELECT * FROM tabelle WHERE float_spalte between 3.45 und 3.55;
@end example

In den meisten Fällen kann dies durch Umwandlung von @code{FLOAT} in
@code{DOUBLE} behoben werden!

@item
Wenn Sie immer noch nicht herausfinden können, was schief geht, erzeugen
Sie einen minimalen Test, der mit @code{mysql test < anfrage.sql} laufen
gelassen werden kann, um Ihre Probleme aufzuzeigen. Sie können eine
Testdatei mit @code{mysqldump --quick datenbanktabellen > anfrage.sql}
erzeugen. Öffnen Sie die Datei in einem Editor, entfernen Sie ein paar
Einfügezeilen (wenn es davon zu viele gibt) und fügen Sie Ihr
SELECT--Statement am Ende der Datei an.

Testen Sie, ob es hiermit immer noch das Problem gibt:

@example
shell> mysqladmin create test2
shell> mysql test2 < anfrage.sql
@end example

Schicken Sie die Testdatei mittels @code{mysqlbug} an
@email{mysql@@lists.mysql.com}.
@end enumerate


@node Table Definition Issues,  , Query Issues, Problems
@c German node Tabellendefinitionsprobleme
@appendixsec Tabellendefinitionsbezogene Themen



@menu
* ALTER TABLE problems::        
* Change column order::         
* Temporary table problems::    
@end menu

@node ALTER TABLE problems, Change column order, Table Definition Issues, Table Definition Issues
@c German node Probleme mit ALTER TABLE
@appendixsubsec Probleme mit @code{ALTER TABLE}.

@tindex ALTER TABLE

@code{ALTER TABLE} ändert eine Tabelle zum aktuellen Zeichensatz. Wenn Sie
während @code{ALTER TABLE} einen Fehler wegen doppelter Schlüsseleinträge
bekommen, liegt das entweder daran, dass die neuen Zeichensätze auf bei
Schlüsseln auf dieselben Werte gemappt sind, oder dass die Tabelle
beschädigt ist, wobei Sie @code{REPAIR TABLE} auf die Tabelle laufen lassen
sollten.

Wenn @code{ALTER TABLE} mit einem Fehler wie folgt stirbt:

@example
Error on rename of './datenbank/name.frm' to './datenbank/B-a.frm' (Errcode: 17)
@end example

Kann das Problem darin bestehen, dass MySQL bei einem vorhergehenden
@code{ALTER TABLE} abgestürzt ist und es eine alte Tabelle namens
@file{A-etwas} oder @file{B-etwas} gibt, die herum liegt. Gehen Sie in
diesem Fall ins MySQL-Daten-Verzeichnis und löschen Sie alle Dateien, die
Namen wie @code{A-} oder @code{B-} haben. (Statt löschen können Sie sie
auch an eine andere Stelle verschieben.)

@code{ALTER TABLE} funktioniert auf folgenden Weise:

@itemize @bullet
@item Erzeugt eine neue Tabellen namens @file{A-xxx} mit den angeforderten
Änderungen.
@item Alle Zeilen der alten Tabelle werden nach @file{A-xxx} kopiert.
@item Die alte Tabelle wird in @file{B-xxx} umbenannt.
@item @file{A-xxx} wird in Ihren alten Tabellennamen umbenannt.
@item @file{B-xxx} wird gelöscht.
@end itemize

Wenn etwas bei dieser Umbennungsoperation fehlschlägt, versucht MySQL, die
Änderungen rückgängig zu machen. Wenn etwas Schwerwiegendes schief geht
(was natürlich passieren kann), läßt MySQL eventuell die alte Tabelle als
@file{B-xxx}, aber ein einfaches Umbenennen auf Systemebene sollte Ihre
Daten zurückbringen.


@node Change column order, Temporary table problems, ALTER TABLE problems, Table Definition Issues
@c German node Änderung der Spalten-Reihenfolge
@appendixsubsec Wie man die Reihenfolge der Spalten in einer Tabelle ändert

@cindex neu sortieren, Spalten
@cindex Spalten, ändern
@cindex ändern, Spalten-Reihenfolge
@cindex Tabellen, Spalten-Reihenfolge ändern

Im großen und Ganzen geht es bei SQL darum, die Applikation vom
Daten-Speicherformat zu abstrahieren. Sie sollten immer die Reihenfolge
angeben, in der Sie Ihre Daten abrufen wollen. Beispiel:

@example
SELECT spalten_name1, spalten_name2, spalten_name3 FROM tabelle;
@end example

Das gibt die Spalten in der Reihenfolge @code{spalten_name1},
@code{spalten_name2}, @code{spalten_name3} zurück, wohingegen:

@example
SELECT spalten_name1, spalten_name3, spalten_name2 FROM tabelle;
@end example

die Spalten in der Reihenfolge @code{spalten_name1}, @code{spalten_name3},
@code{spalten_name2} zurückgibt.

Sie sollten in einer Applikation @strong{NIE} @code{SELECT *} benutzen und
die Spalten basierend auf ihrer Position abrufen, weil die Reihenfolge, in
der Spalten zurückgegeben werden, im Zeitablauf @strong{NICHT} garantiert
werden kann. Eine einfache Änderung in Ihrer Datenbank kann dazu führen,
dass Ihre Applikation dramatisch scheitert.

Wenn Sie dennoch die Spalten-Reihenfolge ändern wollen, können Sie das wie
folgt tun:

@enumerate
@item
Erzeugen Sie eine neue Tabelle mit den Spalten in der richtigen
Reihenfolge.
@item
Führen Sie @code{INSERT INTO neue_tabelle SELECT
felder-in-der-reihenfolge-von-neue_tabelle FROM alte_tabelle} aus.
@item
Löschen Sie @code{alte_tabelle} oder benennen Sie sie um.
@item
Führen Sie @code{ALTER TABLE neue_tabelle RENAME alte_tabelle} aus.
@end enumerate


@node Temporary table problems,  , Change column order, Table Definition Issues
@c German node Probleme mit temporären Tabellen
@appendixsubsec TEMPORARY TABLE-Probleme

@cindex temporäre Tabellen, Probleme

Im Folgenden eine Auflistung der Beschränkungen bei @code{TEMPORARY TABLES}.

@itemize @bullet
@item
Eine temporäre Tabelle kann nur vom Typ @code{HEAP}, @code{ISAM} oder
@code{MyISAM} sein.
@item
Sie können temporäre Tabellen nicht mehr als einmal in derselben Anfrage
benutzen. Folgendes zum Beispiel funktioniert nicht:

@example
select * from temporary_table, temporary_table as t2;
@end example

Das soll in Version 4.0 behoben werden.
@item
Sie können kein @code{RENAME} auf eine @code{TEMPORARY}-Tabelle benutzen.
Beachten Sie, dass @code{ALTER TABLE alter_name RENAME neuer_name} dagegen
funktioniert!
Das soll in Version 4.0 behoben werden.
@end itemize



@c German FIX this appendix should be removed (as was done from English ver.)
@node Benutzer, MySQL-Benutzung durch Kunden, Problems, Top
@c German node <no English equivalent>
@appendix Einige MySQL-Benutzer

@cindex Benutzer, von MySQL
@cindex News-Sites

Dieser Anhang listet einige Benutzer von MySQL auf, die uns ihre
Genehmigung erteilt haben, sie in dieser Dokumentation aufzuführen. Diese
Liste ist bei weitem nicht vollständig, sollte aber eine allgemeine
Vorstellung davon geben, wer MySQL benutzt und wofür es benutzt werden
kann.


@appendixsec Allgemeine News-Sites

@itemize @bullet

@item @uref{http://www.yahoo.com/, Yahoo!}

@item @uref{http://slashdot.org/, Slashdot: Eine Pro-Linux- / Tech-News- und Kommentar-/Diskussions-Site}

@item @uref{http://www.linux.com/, Alles über Linux}

@item @uref{http://www.linuxtoday.com/, Linuxtoday}

@item @uref{http://www.32bitsonline.com/, 32Bits Online: weil es mehr als eine Art zu computern gibt}

@item @uref{http://www.freshmeat.net/, Freshmeat: Neues über neue Versionen und computerbezogene Themen}

@end itemize

@cindex Suchmaschinen, web
@cindex Web-Suchmaschinen
@appendixsec Einige Web-Suchmaschinen

@itemize @bullet

@item @uref{http://www.aaa.com.au, AAA Matilda Web Search}

@item @uref{http://www.whatsnu.com/, What's New}

@item @uref{http://www.aladin.de/, Aladin}

@item @uref{http://www.columbus-finder.de/, Columbus Finder}

@item @uref{http://www.spider.de/, Spider}

@item @uref{http://www.blitzsuche.de/, Blitzsuche}

@item @uref{http://www.indoseek.co.id, Indoseek Indonesien}

@item @uref{http://www.yaboo.dk/, Yaboo - Yet Another BOOkmarker}


@item @uref{http://www.ozsearch.com.au, OzSearch Internet Guide}

@item @uref{http://www.splatsearch.com/, Splat! Search}

@item @uref{http://osdls.library.arizona.edu/, The Open Source Digital Library System Project}
@end itemize

@appendixsec Einige Informations-Suchmaschinen mit Konzentration auf bestimmte Felder

@itemize @bullet

@item @uref{http://www.spylog.ru/, SpyLOG ;  Eine sehr populäre Web-Counter-Site}

@item @uref{http://www.tucows.com/, TuCows Network; Archiv für Freie Software}

@item @uref{http://www.jobvertise.com,Jobvertise: Angebot und Nachfrage nach Jobs}

@item @uref{http://www.musicdatabase.com, die Musik-Datenbank}

@item @uref{http://www.soccersearch.com, Fussball-Suchseite}

@item @uref{http://www.headrush.net/takedown, TAKEDOWN - Ringen}

@item @uref{http://www.lyrics.net, das internationale Liedtext-Netzwerk}

@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://TheMatrix.com/~matrix/bund_search.phtml, Musiker die andere Musiker suchen (kostenloser Service)}

@item @uref{http://www.addall.com/AddBooks/Stores.html,AddALL Büchersuche und Preisvergleich}

@item @uref{http://www.herbaria.harvard.edu/Data/Gray/gray.html,Harvard's Gray Herbarium Index von Pflanzennamen}

@item @uref{http://www.game-Entwickler.com/, die Spiele-Entwicklungs-Suchmaschine}

@item @uref{www.theinnkeeper.com, der Innkeeper Reiseführer}

@item @uref{http://www.macgamedatabase.com/, die Mac-Game-Datenbank benutzt PHP und MySQL}
@c Von: Marc Antony Vose <suzerain@suzerain.com>

@item @uref{http://www.csse.monash.edu.au/publications/, Research
Veröffentlichungen an der Monash University in Australien}

@item @uref{http://www.ipielle.emr.it/bts/index.html,
Berufsbezogene Gesundheits- und Sicherheits-Website-Datenbank (ein Projekt für die ECC)}
@c c.presutti@ipielle.emr.it

@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://data.mch.mcgill.ca/, Bioinformatik-Datenbanken am
Montreal-Kinderkrankenhaus die MySQL benutzen}
@c saeed@www.debelle.mcgill.ca
@end itemize

@cindex Online-Magazine
@cindex magazines, online
@appendixsec Online-Magazine

@itemize @bullet
@item @uref{http://www.spoiler.com, Spoiler Webzine}.
Ein Online-Magazin für Musik, Literatur, Kunst und Design.
@item @uref{http://www.linux-magazin.de/newsflash/, Tägliche Nachrichten über Linux in deutscher Sprache}
@item @uref{http://www.betazine.com,Betazine - Das ultimate Online-Betatester-Magazin}
@item @uref{http://www.currents.net/ccinfo/aboutcc.html,Computer Currents Magazine}
@end itemize

@cindex Websites
@appendixsec Websites die MySQL als Backend benutzen

@itemize @bullet

@item @uref{http://liftoff.msfc.nasa.gov, NASA}
@item @uref{http://kids.msfc.nasa.gov, NASA KIDS}
@item @uref{http://science.nasa.gov, Science@@NASA}

@item @uref{http://www.handy.de/, handy.de}

@item @uref{http://lindev.jmc.tju.edu/qwor, Qt Widget and Object Repository}

@item @uref{http://www.samba-choro.com.br, Brasilianische Samba-Site (auf portugiesisch)}

@item @uref{http://pgss.iss.uw.edu.pl/en_index.ISS, polnische allgemeine Sozial-Umschau}

@item @uref{http://www.expo2000.com, Expo2000} Weltweiter Verkauf von
Ticket für diese Veranstaltung wurde mit MySQL und tcl/tk implementiert.
Mehr als 5.000 Reiseagenturen in der ganzen Welt hatten Zugriff darauf.

@item @uref{http://www.freevote.com/, FreeVote.com ist ein kostenloser
Abstimmungsservice mit Millionen Benutzern.}

@item @uref{http://f1.tauzero.se, Forza Motorsport}

@item @uref{http://www.dreamhost.com/, DreamHost Web-Hosting}

@end itemize

@cindex services
@appendixsec Einige Domain- / Internet- / Web- und verwandte Services

@itemize @bullet

@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://www.wix.com/mysql-hosting, Registrar von Webprovidern
die MySQL unterstützen}

@item @uref{http://www.yi.org/, dynamische DNS-Services}

@item @uref{http://www.dynodns.net/, dynamischer Domain-Name-Service}

@item @uref{http://www.ods.org/, Open DNS Project; kostenloser dynamischer DNS-Service}

@c @item @uref{http://dynodns.net, kostenlose dynamische DNS-Implementation}
@c EMAIL: A Moore <amoore@mooreSysteme.com>

@item @uref{http://www.hn.org/, Hammernode; öffentliche DNS-Server}

@item @uref{http://www.fdns.net/, kostenlose 3rd-Level-Domains}

@item @uref{http://worldcommunity.com/, Online-Datenbank}

@item @uref{http://www.bigbiz.com, BigBiz Internet-Services}

@item @uref{http://virt.circle.net, The Virt Gazette}

@item @uref{http://www.california.com, Global InfoNet Inc}

@item @uref{http://www.webhosters.com, WebHosters - ein Führer für WWW-Provider}

@item @uref{http://online.dn.ru, Internet-Informations-Server}

@item @uref{http://www.stopbit.com, eine Technologie-News-Site}

@item @uref{http://www.worldnetla.net, WorldNet Communications - ein Internet Service Provider}

@item @uref{http://www.netizen.com.au/, Netizen: Web-Beratung in Australien}

@item @uref{http://www.trainingpages.co.uk, Suchseite für Trainingskurse in Großbritannien}

@item @uref{http://chat.nitco.com, Gannon Chat (GPL). Geschrieben in Perl und JavaScript}

@item @uref{http://www.addurls.com/, ein allgemeines Links-Verzeichnis}

@item @uref{http://www.bookmarktracker.com, ein Web-basierender Bookmark-Verwaltungs-Service}

@item @uref{http://www.cdrom.com,Walnut Creek CDROM}

@item @uref{http://www.wwwThread.org/, WWWThread; interaktive Diskussionsforen}

@item @uref{http://pvmon.portici.enea.it/Meteo, auf italienisch; Datenspeicherung von meteo station}

@item @uref{http://www.buysell.net/, Online-"Person To Person"-Auktion}

@item @uref{http://tips.pair.com, Tipps zur Web-Entwicklung}

@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://www.mailfriends.com, Mailfriends.com ist ein kostenloser Service für jeden der über das Internet einen Freund finden will.}

@item @uref{http://www.uninova.com/cgi-bin/wctelnets?list, Website Telnet BBS List}

@item @uref{http://www.uninova.com/cnc.html, UniNova Digitale Postkarten}

@c @item @uref{http://cabinboy.powersurfr.com, eine Internet-RFC-Suchmaschine}

@item @uref{http://www.dslreports.com, DSL-Provider-Suche mit Testberichten}.
Mit MySQL und Modperl hergestellt. Alle Seiten werden dynamisch aus einer
MySQL-Datenbank erzeugt.
@end itemize

@cindex PHP, Websites
@appendixsec Websites, die @code{PHP} und MySQL benutzen

@itemize @bullet
@c @item @uref{http://www.wh200th.com, Site zum 200. Jahrestag des Weißen Hauses}

@item @uref{http://support.jgaa.com/, Jgaa's Internet - Offizielle Support-Site}

@item @uref{http://io.incluso.com, Ionline - online publication:} MySQL, PHP, Java, Web-Programmierung, DB-Entwicklung

@item @uref{http://www.baboo.com, BaBoo(Browse und bookmark). Kostenloser Web-basierender Bookmarkmanager und Kalender}

@item @uref{http://www.courses.pjc.cc.fl.us/Schedule/index.php, Kursplanungssystem am Pensacola Junior College}

@item @uref{http://www.fccj.org, Florida Community College in Jacksonville}

@item @uref{http://www.32bit.com/, 32bit.com; Ein umfangreiches Shareware- / Freeware-Archiv}

@item @uref{http://www.jokes2000.com/, Jokes 2000}
@c Added 990604; EMAIL: ah@dybdahl.dk


@item @uref{http://www.burken.nu/ , Burken.NU} Burken ist ein Webhotel, das Skripte unter anderem für entfernte Benutzer zur Verfügung stellt, beispielsweise Counter, Gästebücher usw.
@c Added 990608; EMAIL: spacedmp@SpaceDump.Burken.NU (Anders Olausson)

@item @uref{http://tips.pair.com, tips.pair.com} Enthält Tipps zu HTML, JavaScript, 2D-/3D-Grafiken und PHP3/MySQL. Alle Seiten werden aus einer Datenbank erzeugt.
@c Added 990614; EMAIL: downey@image.dk (Rune Madsen)

@item @uref{http://www.Softwarezrus.com/, Softwarezrus.com} E-Commerce-Site, die Computer verkauft.
@end itemize

@cindex Berater, Auflistung
@appendixsec Einige MySQL-Berater

@itemize @bullet

@item @uref{http://iConnect.de, iConnect GmbH Berlin}

@item @uref{http://www.ayni.com, Ayni AG}

@item @uref{http://worldcommunity.com/, Online-Datenbank}

@item @uref{http://www2.dataguard.no/,DataGuard (mit MySQL und PHP)}

@item @uref{http://wwits.net/programs/mysql.phtml, WWITS (mit MySQL und PHP)}

@item @uref{http://www.worldcommunity.com/, WCN - The World Community Network}

@item @uref{http://www.chipcastle.com, Chip Castle Dot Com Inc}
@c Added 990603 EMAIL: chip@chipcastle.com (Chip Castle)

@item @uref{http://www.cyber.com.au/, Cybersource Pty. Ltd}

@item @uref{http://www.spring.de, Spring infotainment GmbH & Co. KG}
@c added 990905 "Oliver Pischke" <opischke@spring.de>

@item @uref{http://www.wamdesign.com/, Entwickelt Websites mit MySQL}
@c Added 990905; max@wamdesign.com

@item @uref{http://www.berkeleyconsultants.com, Berkeley-Berater-Gruppe}

@item @uref{http://www.jammconsulting.com/, JAMM Consulting Inc.}

@end itemize

@appendixsec Programmierung

@cindex Websites, verschiedene
@appendixsec Nicht kategorisierte Seiten

@itemize @bullet

@item @uref{http://www.feature-showcase.com/htmls/demo_mysql.sql, AZC.COM's Feature Showcase}

@item @uref{http://www.teach.org.uk/subjects/trainingcourse/g.html, Kurssuche}

@item @uref{http://www.northerbys.com, Northerbys Online-Auktionen}

@item @uref{http://www.schiphol.nl/flights/home.htm, Amsterdamer Flughafen Schiphol}

@item @uref{http://TheMatrix.com/seventhsin/query.phtml, CD-Datenbank}

@item @uref{http://TheMatrix.com/~flmm/GEAR.html, Datenbank gebrauchter Audio-Geräte}

@item @uref{http://www.kiss.de/musik-mueller, Notenblätter}

@item @uref{http://www.bagism.com, Bagism - Eine John-Lennon-Fanseite}

@item @uref{http://www.selftaught.com/, US-Folkart-Broker}

@item @uref{http://organizer.net/, Mail lesen auf dem Web}

@item @uref{http://www.mypage.org/, Kostenlose Homepages auf www.somecoolname.mypage.org}

@item @uref{http://www.schulweb.de/, Der Server für Schulen im Web (auf deutsch)}

@item @uref{http://www.ald.net/, Auldhaefen Online-Services}

@item @uref{http://www.cary.net/, CaryNET Information Center}

@item @uref{http://www.Dataden.com/, Dataden Computer Systems}

@item @uref{http://undree.grm.se/ undr@'emuseet (auf schwedisch)}

@item @uref{http://www.him.net/, HOMESITE Internet Marketing}

@item @uref{http://www.jade-v.com/techinfo.html, Jade-V Network Services }

@item @uref{http://ww2010.atmos.uiuc.edu/(Gl)/abt/aknw/tech.rxml, Weather World 2010 Technical Credits} @*

@item @uref{http://gimp.foebud.org/registry/doc/, Über die Gimp-Plugin-Registrierung}

@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://www.fast-inc.com/produkte/Archiver/database.html, Java-Werkzeug Archiver technical detail (leicht optimistisch was die MySQL-ANSI-92-Kompatibilität betrifft)}

@item @uref{http://www.gamesdomain.com/cheats/usrcheat.phtml, Games Domain Cheats Datenbank}

@item @uref{http://www.kcilink.com/poweredby/, The "Powered By" Page (Kcilink)}

@item @uref{http://www.netcasting.net/index.whtml, Netcasting}

@item @uref{http://homepages.tig.com.au/~mjj/nblTipps, NBL (Australian National Basketball League) tipping}

@item @uref{http://www.cgishop.com/, CGI-Shop}

@item @uref{http://www.whirlycott.com/, Whirlycott: Website-Design}

@item @uref{http://www.mtp.dk, Museum Tusculanum Press}

@item @uref{http://csdgi.historie.ku.dk/biblio, Centro Siciliano di Documentazione}

@item @uref{http://caribou.dyn.ml.org:8000, Quake-Statistik-Datenbank}

@item @uref{http://www.astroforum.ch, Astroforum: Astrologie und verwandte Dinge (auf deutsch)}

@item @uref{http://www.opendebate.com, OpenDebate - Interaktive Umfragen & Offene Diskussionen}

@item @uref{http://vermeer.organik.uni-erlangen.de/dissertationen/, Online-Server für Dissertationen im Bereich Chemie}

@item @uref{http://www.freschinfo.com, FreSch! The Free Scholarship Search Service}

@item @uref{http://www.nada.kth.se/~staffanu/pinball, Stockholmer Flipper-Finder}

@item @uref{http://www.hek.com, HEK - eine Baufirma}

@item @uref{http://www.nbi.nl, Elsevier Business Information}

@item @uref{http://vaccination.medicallink.se/, Medizinische Links (mit ColdFusion und MySQL)}

@item @uref{http://www.joblink-usa.com, Suche nach Jobs & Leuten auf JobLink-USA}

@item @uref{http://www.skydive.net/competfs, Competition Formation Skydiving}

@item @uref{http://www.galaxy-net.net/Galaxy-NET Telecommunikation, E-Commerce und interne Buchhaltung}

@item @uref{http://www.borsen.dk/, Dänemarks führende Wirtschaftszeitung B@o{}rsen}

@item @uref{http://tmmm.simplenet.com/indb/, Die Internet-NES-Datenbank}

@item @uref{http://www.russia.cz, Reisebüro in Prag in 3 Sprachen}

@item @uref{http://www.linkstation.de, Linkstation}

@item @uref{http://www.peoplestaff.com, Durchsuchbare Online-Datenbank bei Peoplestaff}

@item @uref{http://www.dreamhorse.com, Durchsuchbares Datenbank-System für Pferde-bezogene Werbung}

@item @uref{http://pootpoot.com/,The Poot site}

@item @uref{http://grateful.net/hw_html/,"Playin' in the LAN"; Netzwerk-Monitoring-Suite}

@c Update von Christopher Milton <cmilton@bwn.net> 1999-12-21
@item @uref{http://www.usapa.army.mil,U.S. Army Publishing Agency}

@item @uref{http://www.nekretnine.co.yu/,Makler in Jugoslawien}

@item @uref{http://demo.cpsoft.com/pims/devFAQ.html, PIMS; Patienten-Informations-Management-System}

@item @uref{http://cpsoft.com,Pilkington Software Inc}

@item @uref{http://www.no-quarter.org/, Memorial für Vietnam-Veteranen (The Wall) - Datenbank}

@item @uref{http://www.gamers-union.com/,Gamer's Union ist auf Auktionen für gebrauchtes und nicht mehr gedrucktes Spiele-Material spezialisiert}

@item @uref{http://www.montereyhigh.com/office/dbul.php3, Ein tägliches Bulletin an der Monterey-Highschool}

@item @uref{http://www.myEastside.com,Website der Gemeinde Lake
Washington's Eastside für Einwohner und Unternehmen}

@item @uref{http://bowling-france.net/, Französische Bowling-Site}
@end itemize

Schicken Sie Ergänzungen dieser Liste an @email{webmaster@@mysql.com}.

@page




@node MySQL-Benutzung durch Kunden, Contrib, Benutzer, Top
@c German node <no English equivalent>
@appendix MySQL-Benutzung durch Kunden

@cindex MySQL-Benutzung

Der Abschnitt 'Einige MySQL-Benutzer' enthält viele verschiedene Links zu
MySQL-Benutzern, aber wenig Informationen darüber, wie diese MySQL
benutzen. @xref{Benutzer}. Dieser Handbuch-Abschnitt soll Ihnen Anregungen
geben, wie MySQL für Problemlösungen eingesetzt wird.

Dieser Abschnitt ist neu und wir planen, hier in Bälde weitere Geschichten
unterzubringen. Wenn Sie Interesse haben, teilzunehmen, und erzählen
wollen, wie Sie MySQL in einer einzigartigen Umgebung nutzen, oder
Erfolgsgeschichten zu Ihrer Benutzung von MySQL haben, schreiben Sie an
@code{docs@@mysql.com} mit Betreff @code{Success:}. Beachten Sie, dass es
einige Zeit bis zur Beantwortung dauern kann, da wir sehr beschäftigt sind.

@itemize @bullet
@item 
@strong{Peter Zaitsev von Spylog.ru} schreibt:
Ich denke, die Größe meiner Datenbank könnte für Euch interessant sein.
Die gesamte Datenbank liegt momentan auf 15 Servern und enthält etwa 60.000
Tabellen, die etwa 5.000.000.000 Zeilen enthalten. Mein unter der höchsten
Last stehender Server hat momentan etwa 10.000 Tabellen mit 1.000.000.000
Zeilen. Die größten Tabellen enthalten etwa 50.000.000 Zeilen, und dieser
Wert wird sich noch steigern, wenn ich auf den 2.4-Kernel mit großen
Dateien umstelle. Momentan muss ich viele Logs für große Sites löschen, um
Tabellengröße unter 2 GB zu halten.

@item
@strong{Texas Instruments} benutzt MySQL für die Handhabung von Tabellen,
die bis zu 2 Milliarden Zeilen in einer Validations-Regressions-Datenbank
enthalten.
@end itemize

@page




@node Contrib, Credits, MySQL-Benutzung durch Kunden, Top
@c German node Contrib
@appendix Beigesteuerte Programme

@cindex Beigesteuerte Programme
@cindex Programme, beigesteuerte

Viele Benutzer von MySQL haben @emph{sehr} nützliche Support-Werkzeuge und
Add-ons beigesteuert.

@ifclear web
Eine Auflistung, was unter @uref{http://www.mysql.com/Downloads/Contrib/}
(oder einem Mirror) verfügbar ist, steht unten. Wenn Sie
MySQL-Unterstützung für die Perl-@code{DBI}/@code{DBD}-Schnittstelle bauen
wollen, sollten Sie sich @code{Data-Dumper}, @code{DBI} und die
@code{Msql-Mysql-modules}-Dateien holen und installieren.
@xref{Perl}.
@end ifclear

@appendix sec-APIs

@cindex Perl, Module
@itemize @bullet
@item Perl-Module
@itemize @minus
@item @uref{http://www.mysql.com/Downloads/Contrib/Data-Dumper-2.101.tar.gz, Data-Dumper-2.101.tar.gz}
Perl-@code{Data-Dumper}-Module. Nützlich für
@code{DBI}/@code{DBD}-Unterstützung für ältere Perl-Installationen.

@item @uref{http://www.mysql.com/Downloads/Contrib/DBI-1.15.tar.gz, DBI-1.15.tar.gz}
Perl-@code{DBI}-Module.

@item @uref{http://www.mysql.com/Downloads/Contrib/KAMXbase1.2.tar.gz,KAMXbase1.2.tar.gz}
Konvertiert zwischen @file{.dbf}-Dateien und MySQL-Tabellen. Perl-Module
geschrieben von Pratap Pereira @email{pereira@@ee.eng.ohio-state.edu},
erweitert von Kevin A. McGrail
@email{kmcgrail@@digital1.peregrinehw.com}. Dieser Konverter kann
MEMO-Felder handhaben.

@item @uref{http://www.mysql.com/Downloads/Contrib/Msql-Mysql-modules-1.2216.tar.gz, Msql-Mysql-modules-1.2216.tar.gz}
Perl-@code{DBD}-Module, um auf mSQL- und MySQL-Datenbanken zuzugreifen.

@item @uref{http://www.mysql.com/Downloads/Contrib/Data-ShowTable-3.3.tar.gz,  Data-ShowTable-3.3.tar.gz}
Perl-@code{Data-ShowTable}-Module. Nützlich für @code{DBI}/@code{DBD}-Unterstützung.

@item @uref{http://www.mysql.com/Downloads/Contrib/HandySQL-1.1.tar.gz, HandySQL-1.1.tar.gz}
HandySQL ist ein MySQL-Zugriffsmodul. Es bietet eine C-Schnittstelle, die
in Perl eingebettet ist und ist ungefähr 20% schneller als reguläres DBI.

@end itemize

@cindex JDBC
@item JDBC
@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-1.2c.tar.gz, mm.mysql.jdbc-1.2c.tar.gz}
Der mm-JDBC-Treiber für MySQL. Das ist ein Produktions-Release und wird
aktiv weiter entwickelt. Von Mark Matthews (@email{mmatthew@@ecn.purdue.edu}).

@item @uref{http://www.mysql.com/Downloads/Contrib/mm.mysql.jdbc-2.0pre5.tar.gz, mm.mysql.jdbc-2.0pre5.tar.gz}
Der mm-JDBC-Treiber für MySQL. Das ist eine Pre-Release-Beta-Version und
wird aktiv weiter entwickelt. Von Mark Matthews (@email{mmatthew@@ecn.purdue.edu}).
Die beiden obigen Treibern stehen unter LGPL-Lizenz. Bitte sehen Sie unter
@uref{http://www.worldserver.com/mm.mysql/} nach den aktuellsten Treibern
nach (und wegen weiterer JDBC-Informationen), weil diese Treibern
vielleicht schon veraltet sind.

@item @uref{http://www.caucho.com/Projekte/jdbc-mysql/index.xtp}
Der kommerzielle Resin-JDBC-Treiber, der unter Open Source veröffentlicht
wird. Er behauptet, schneller als der mm-Treiber zu sein, aber wir haben
darüber bislang noch nicht viele Informationen.

@item @uref{http://www.mysql.com/Downloads/Contrib/twz1jdbcForMysql-1.0.4-GA.tar.gz, twz1jdbcForMysql-1.0.4-GA.tar.gz}
Der twz-Treiber: Ein Typ-4-JDBC-Treiber von Terrence W. Zellers
@email{zellert@@voicenet.com}. Dieser ist kommerziell, aber kostenlos für
privaten und Schulungsgebrauch. (Wird nicht mehr unterstützt.)
@c no answer von Server 990830
@c You can always find the latest Treiber at @uref{http://www.voicenet.com/~zellert/tjFM/}.
@item @uref{http://www.mysql.com/Downloads/Contrib/pmdamysql.tgz,pmdamysql.tgz}
Ein MySQL-PMDA. Stellt MySQL-Serverstatus- und Konfigurationsvariablen zur
Verfügung.
@end itemize

@cindex OLEDB
@item OLEDB
@itemize @bullet
@item @uref{http://www.mysql.com/downloads/Win32/MyOLEDB.exe, MyOLEDB.exe}
OLEDB-Handler für MySQL. Von SWsoft.
@item @uref{http://www.mysql.com/downloads/Win32/MySamples.zip, MySamples.zip}
Beispiele und Dokumentation für MyOLEDB. Von SWsoft.
@item @uref{http://www.mysql.com/downloads/Win32/Myoledb.zip, Myoledb.zip}
Quelltext für MyOLEDB. Von SWsoft.
@item @uref{http://www.mysql.com/downloads/Win32/MyOLEDB.chm, MyOLEDB.chm}
Hilfedateien für MyOLEDB.
@item @uref{http://www.mysql.com/downloads/Win32/libmyodbc.zip, libmyodbc.zip}
Statische MyODBC-Bibliothek zum Bauen von MyOLEDB. Basiert auf MyODBC-Code.
@end itemize

@cindex C++
@item C++
@itemize @bullet

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-c++-0.02.tar.gz, mysql-c++-0.02.tar.gz}
MySQL-C++-Wrapper-Bibliothek. Von Rolund Haenel,
@email{rh@@ginster.net}.

@item @uref{http://www.mysql.com/Downloads/Contrib/MyDAO.tar.gz, MyDAO}
MySQL-C++-API. Von Satish @email{spitfire@@pn3.vsnl.net.in}. Inspiriert
von Rolund Haenels C++-API und Ed Carps MyC-Bibliothek.

@item @uref{http://www.mysql.com/download_mysql++.html, mysql++}
MySQL-C++-API (mehr als nur eine Wrapper-Bibliothek). Ursprünglich von
@email{kevina@@clark.net}. Mittlerweile gepflegt von Sinisa bei MySQL AB.

@item @uref{http://nelsonjr.homepage.com/NJrAPI,NJrAPI}
Eine in C++ geschriebene, Datenbank-unabhängige Bibliothek, die MySQL
unterstützt.
@end itemize

@cindex Delphi
@item Delphi
@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/delphi-interface.gz, delphi-interface.gz}
Delphi-Schnittstelle zu @code{libmysql.dll}, von Blestan Tabakov,
@email{root@@tdg.bis.bg}.

@item @uref{http://www.mysql.com/Downloads/Contrib/DelphiMySQL2.zip, DelphiMySQL2.zip}
Delphi-Schnittstelle zu @code{libmysql.dll}, von @email{bsilva@@umesd.k12.or.us}.

@item @uref{http://www.mysql.com/Downloads/Contrib/Udmysel.pas, Udmysql.pas}
Ein Wrapper für libmysql.dll für die Benutzung in Delphi. Von Reiner Sombrowsky.

@item @uref{http://www.fichtner.net/delphi/mysql.delphi.phtml, Eine Delphi-Schnittstelle zu MySQL.}
Mit Quelltext. Von Matthias Fichtner.

@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://www.productivity.org/projects/tmysql/, @strong{TmySQL}
Eine Bibliothek um MySQL mit Delphi zu benutzen}.

@item @uref{http://www.geocities.com/CapeCanaveral/2064/mysql.html, Delphi TDataset-component}.
@item
@item @uref{http://www.mysql.com/Downloads/Contrib/Win32/SBMySQL50Share.exe, Delphi 5 Shareware MySQL Dataset Components}
@end itemize

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-ruby-2.2.0.tar.gz, mysql-ruby-2.2.0.tar.gz}
MySQL Ruvon module. Von TOMITA Masahiro @email{tommy@@tmtm.org}
@uref{http://www.netlab.co.jp/ruby/, Ruby} ist eine objektorientierte Interpretersprache.

@item @uref{http://www.mysql.com/Downloads/Contrib/JdmMysqlTreiber-0.1.0.tar.gz,JdmMysqlTreiber-0.1.0.tar.gz}
Ein VisualWorks 3.0 Smalltalk-Treiber für MySQL. Von
@email{joshmiller@@earthlink.net}.

@item @uref{http://www.mysql.com/Downloads/Contrib/Db.py, Db.py}
Python-Modul mit Caching. Von @email{gundalf@@rosmail.com}.

@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLmodule-1.4.tar.gz, MySQLmodule-1.4.tar.gz}
Python-Schnittstelle für MySQL. Von Joseph Skinner @email{joe@@earthlight.co.nz}. Geändert von Joerg Senekowitsch @email{senekow@@ibm.net}.

@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-python-0.3.0.tar.gz, MySQL-python-0.3.0.tar.gz}
MySQLdb-Python ist eine DB-API v2.0-kompatible Schnittstelle zu MySQL.
Transaktionen werden unterstützt, wenn der Server und die Tabellen sie
unterstützen. Sie ist Thread-sicher und enthält ein Kompatibilitätsmodul
für älteren Code, der für die nicht mehr gepflegte
MySQLmodule-Schnittstelle geschrieben wurde.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mex_12.tar.gz, mysql_mex_1_12.tar.gz}
Ein Schnittstellenprogramm für das Matlab-Programm von MathWorks. Die
Schnittstelle wurde von Kimmo Uutela und John Fisher (nicht von Mathworks)
hergestellt. Siehe
@uref{http://boojum.hut.fi/~kuutela/mysqlmex.html,mysqlmex.html} wegen
weiterer Informationen.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltcl-1.53.tar.gz, mysqltcl-1.53.tar.gz}
Tcl-Schnittstelle für MySQL. Basiert auf @file{msqltcl-1.50.tar.gz}.
Aktualisiert von Tobias Ritzau, @email{tobri@@ida.liu.se}.

@item @uref{http://www.mysql.com/Downloads/Contrib/MyC-0.1.tar.gz, MyC-0.1.tar.gz}
Eine Visual-Basic-ähnliche API von Ed Carp.

@item @uref{http://www.mysql.com/Downloads/Contrib/sqlscreens-1.0.1.tar.gz, sqlscreens-1.0.1.tar.gz}
Tcl/Tk-Code, um Datenbank-Screens zu erzeugen. Von Jean-Francois Dockes.

@item @uref{http://www.mysql.com/Downloads/Contrib/Vdb-dflts-2.1.tar.gz, Vdb-dflts-2.1.tar.gz}
Das ist eine neue Version eines Satzes von Bibliothek-Dienstprogrammen, die
eine generische Schnittstelle zu SQL-Datenbank-Maschinen zur Verfügung
stellen, um Ihre Applikation zu einer Stufe-3-Applikation (3-Tier) zu
machen. Der Vorteil ist, dass Sie sehr einfach zwischen verschiedenen
Datenbank-Maschinen umschalten bzw. zu anderen Datenbanken wechseln können.
Sie implementieren einfach eine Datei für das neue Backend und brauche
keinerlei Änderungen an Ihren Applikationen vorzunehmen. Von
@email{damian@@cablenet.net}.

@item @uref{http://www.mysql.com/Downloads/Contrib/DbFramework-1.10.tar.gz, DbFramework-1.10.tar.gz}
DbFramework ist eine Sammlung von Klassen zur Manipulation von
MySQL-Datenbanken. Die Klassen basieren lose auf der CDIF Data Model
Subject Area. Von Paul Sharpe @email{paul@@miraclefish.com}.

@item @uref{http://www.mysql.com/Downloads/Contrib/pike-mysql-1.4.tar.gz, pike-mysql-1.4.tar.gz}
MySQL-Modul für pike. Zur Benutzung mit dem Roxen-Webserver.

@item @uref{http://www.mysql.com/Downloads/Contrib/squile.tar.gz, squile.tar.gz}
Modul für @code{guile}, das es @code{guile} erlaubt, mit SQL-Datenbanken zu
interagieren. Von Hal Roberts.

@item @uref{http://www.mysql.com/Downloads/Contrib/stk-mysql.tar.gz, stk-mysql.tar.gz}
Interface für Stk. Stk ist Tk-widgets mit Scheme darunter anstelle von Tcl.
Von Terry Stefan.

@item @uref{http://www.mysql.com/Downloads/Contrib/eiffel-wrapper-1.0.tar.gz,eiffel-wrapper-1.0.tar.gz}
Eiffel-Wrapper von Michael Ravits.

@item @uref{http://www.mysql.com/Downloads/Contrib/SQLmy0.06.tgz,SQLmy0.06.tgz}
Ersetzbarer FlagShip-Datenbank-Treiber (RDD) für MySQL. Von Alejundro
Fernundez Herrero.
@uref{http://www.fship.com/rdds.html, Flagship-RDD-Homepage}

@item @uref{http://www.mysql.com/Downloads/Contrib/mydsn-1.0.zip,mydsn-1.0.zip}
Binärdatei und Quellcode für @code{mydsn.dll}. mydsn sollte benutzt werden,
um die DSN-Registrierungsdatei für den MyODBC-Treiber in
Coldfusion-Applikationen zu bauen und zu entfernen. Von Miguel Angel
Solórzano.

@item @uref{http://www.mysql.com/Downloads/Contrib/MySQL-ADA95_API.zip, MySQL-ADA95_API.zip}
Eine ADA95-Schnittstelle zur MySQL-API. Von Francois Fabien.

@item @uref{http://www.mysql.com/Downloads/Contrib/MyTool-DLL_for_VB_und_MySQL.zip, MyTool-DLL_for_VB_und_MySQL.zip}
Eine DLL mit MySQL-C-API für Visual Basic. 
Von Ken Menzel @email{kenm@@icarz.com}.

@item @uref{http://www.mysql.com/Downloads/Contrib/MYSQLX.EXE, MYSQL.EXE}
MySQL-ActiveX-Objekt für den direkten Zugriff auf Ihre MySQL-Server von
IIS/ASP, VB und VC++ aus, der die langsameren ODBC-Methoden überspringt.
Voll aktualisierbar, multi-threaded mit voller Unterstützung für alle
MySQL-Feldtypen (Version 2001.1.1). Von SciBit @uref{http://www.scibit.com/}.

@item @uref{http://www.fastflow.it/mylua/, MyLUA Homepage}
Wie man die LUA-Sprache benutzt, um MySQL-@code{PROCEDURE} zu schreiben,
das zur Laufzeit geladen werden kann.

@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/lua-4.0.tar.gz, Lua 4.0}
LUA 4.0
@item @uref{http://www.mysql.com/Downloads/Contrib/mylua-3.23.32.1.tar.gz, mylua-3.23.32.1.tar.gz}
Patch für MySQL 3.23.32, um LUA 4.0 zu benutzen. Von Cristian Giussani.
@end itemize

@item @uref{http://www.mysql.com/Downloads/Contrib/patched_myodbc.zip, patched_myodbc.zip}
Patch (für Omniform-4.0-Unterstützung) des MyODBC-Treibers.
Von Thomas Thaele @email{tthaele@@papenmeier.de}

@end itemize

@appendixsec  Clients

@itemize @bullet
@item Grafische Clients
@itemize @minus
@item @uref{http://www.ideit.com/produkte/dbvis/, DbVisualizer}.
Freeware-JDBC-Client, der Daten und Strukturen mehrerer Datenbanken auf
einmal grafisch visualisiert. Von Innovative-IT Development AB.

@item @uref{http://www.mysql.com/downloads/gui-clients.html, MySQLGUI}
Die MySQL-GUI-Client-Homepage. Von Sinisa bei MySQL AB.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_navigator_0.9.0.tar.gz, MySQL Navigator 0.9}
MySQL Navigator ist ein MySQL-Datenbank-Server-GUI-Client-Programm. Der
Zweck von MySQL Navigator ist, eine nützliche Schnittstelle zu
MySQL-Datenbank-Servern zur Verfügung zu stellen, wobei mehrere
Betriebssysteme und Sprachen unterstützt werden. Momentan können Sie
Datenbanken importieren / exportieren, Anfragen eingeben, Ergebnismengen
holen, Skripte editieren, Skripte laufen lassen, Benutzer hinzufügen,
ändern und löschen, und Client- und Server-Informationen abrufen. Benutzt
QT 2.2. GPL @uref{http://sql.kldp.org/mysql, Homepage für MySQL Navigator}.

@item @uref{http://www.mysql.com/downloads/Win32/secman.zip,  MySQL-Sicherheits-GUI}
Eine Benutzer- und Sicherheitsverwaltungs-GUI für MySQL unter Windows. 
Von Martin Jeremic.
@uref{http://jsoft.webjump.com/, Homepage für MySQL-Sicherheits-GUI}.

@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1.tar.gz, kmysqladmin-0.4.1.tar.gz}.
@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.src.rpm, kmysqladmin-0.4.1-1.src.rpm}.
@item @uref{http://www.mysql.com/Downloads/Contrib/kmysqladmin-0.4.1-1.i386.rpm, kmysqladmin-0.4.1-1.i386.rpm}
Ein Verwaltungswerkzeug für den MySQL-Server, das QT / KDE benutzt. Nur
unter Linux getestet.

@item
@uref{http://www.mysql.com/Downloads/Contrib/mysql-admin-using-java+swing.tar.gz, Java client mit Swing} Von Fredy Fischer,
@email{se-afs@@dial.eunet.ch}. Sie finden die letzte Version immer unter
@uref{http://www.trash.net/~ffischer/admin/index.html, hier}.

@item @uref{http://www.mysql.com/downloads/Win32/MySQL-Maker-1.0.zip,MySQL-Maker 1.0}.
Shareware-MySQL-Client für Windows. Ein WYSIWYG-Werkzeug, mit dem Sie
Datenbanken und Tabellen erzeugen, ändern und löschen können. Sie können
die Feldstruktur ändern, Felder hinzufügen und Daten hinzufügen, ändern und
löschen, direkt ohne ODBC-Treiber.
@uref{http://www.presult.de/presult/frames/fs_mysqlmaker.html, MySQL-Maker-Homepage}

@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlwinadmn.zip, mysqlwinadmn.zip}
Windows-GUI (nur Binärdatei) zur Verwaltung einer Datenbank, von David B. Mansel,
@email{david@@zhadum.org}.

@item @uref{http://home.online.no/~runeberg/myqa, MyQA}
Ein Linux-basierender Anfrage-Client für den MySQL-Datenbank-Server. Mit
MyQA können Sie SQL-Anfragen eingeben, diese ausführen und die Ergebnisse
betrachten, alles in einer grafischen Benutzerschnittstelle. Die GUI ähnelt
grob dem 'Anfrage-Analyzer'-Client, der mit dem Microsoft SQL-Server
ausgeliefert wird.

@item @uref{http://members.xoom.com/_opex_/mysqlmanager/index.html, MySQL-Manager}
Ein grafischer MySQL-Server-Manager für MySQL-Server. Geschrieben in Java,
für Windows.


@item @uref{http://www.mysql.com/downloads/Win32/netadmin.zip, netadmin.zip}
Ein Verwaltungswerkzeug für MySQL unter Windows 95/98 und Windows NT 4.0.
Nur getestet mit MySQL-Versions 3.23.5 bis 3.23.7. Geschrieben mit den
Tmysql-Komponenten.

Sie können Anfragen schreiben und Tabellen darstellen, Indexe,
Tabellensyntax sowie Benutzer, Host und Datenbank verwalten und vieles
mehr. Das Werkzeug ist eine Beta-Version und hat noch viele Bugs. Sie
können das Programm mit allen Features testen. Bitte schicken Sie Bugs und
Hinweise an Marco Suess @email{ms@@it-netservice.de}. Original-URL
@url{http://www.it-netservice.de/pages/Software/index.html}.

@item @uref{http://www.mysql.com/downloads/Win32/netadmin2.zip, netadmin2.zip}
Neue Version von netadmin. Siehe oben wegen Details.

@item @uref{http://www.mysql.com/downloads/Win32/ARTADMIN203.EXE,Atronic's MySQL-Client für Windows 2.0.3.0}.
Die Homepage hierfür ist unter @uref{http://www.artronic.hr}.

@item @uref{http://www.mysql.com/downloads/Win32/mysqlfront.zip, mysqlfront}
Homepage: @uref{http://www.mysqlfront.de/}.
Win32-Client für die Verwaltung von Datenbanken, Tabellen, Tabellendaten,
Indexen und Import-/Export-Dateien. Freeware. Von Ansgar Becker.

@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://www.mysql.com/downloads/Win32/W9xstop.zip,Dienstprogramm
von Artronic um MySQL unter Windows 9x anzuhalten}.

@item @uref{http://bardo.hyperlink.cz/mysqlmon,ein leichtgewichtiger GUI-Client für Windows}.

@item @uref{http://dbtools.vila.bol.com.br/, DB-Werkzeuge}
Ein Werkzeug zur Verwaltung von MySQL-Datenbanken. Momentan nur für
Windows. Einige Features:
@itemize @bullet
@item Verwaltung von Servern, Datenbanken, Tabellen, Spalten, Indexen und
Benutzern.
@item Import-Assistent, um Strukturen und Daten von MS Access, MS Excel,
Dbase, FoxPro, Paradox und ODBC Datenbanken zu übernehmen.

@item @uref{http://www.mysql.com/Downloads/Contrib/KMYENG113.zip,KMYENG113.zip}
Eine Verwaltungs-GUI für MySQL. Funktioniert nur unter Windows, kein
Quellcode verfügbar. Verfügbar in englisch und japanisch. Von Mitunobu Kaneko.
Homepage: @uref{http://sql.jnts.ne.jp/}
@end itemize

@item @uref{http://www.mysql.com/Downloads/Contrib/xmysqladmin-1.0.tar.gz, xmysqladmin-1.0.tar.gz}
Ein X-basierendes Frontend zur MySQL-Datenbank-Maschine. Erlaubt Neuladen,
Status-Prüfungen, Prozesssteuerung, myisamchk, grant/revoke-Berechtigungen,
Erzeugung von Datenbanken, Löschen von Datenbanken, Erzeugen, Ändern,
Durchsuchen und Löschen von Tabellen. Original von Gilbert Therrien,
@email{gilbert@@ican.net}, jetzt aber Public Domain und von MySQL AB
unterstützt.

@item @uref{http://www.mysql.com/Downloads/Contrib/xmysql-1.9.tar.gz, xmysql-1.9.tar.gz}.
@item @uref{http://web.wt.net/~dblhack, xmysql-Homepage}
Ein Frontend zur MySQL-Datenbank-Maschine, mit der man auf einfache Weise
Anfragen und Tabellenwartung durchführen kann sowie Stapel-Anfrragen. Von
Rick Mehalick, @email{dblhack@@wt.net}.
Erfordert @uref{http://bragg.phys.uwm.edu/xforms,xforms 0.88}, um zu
funktionieren.
@item @uref{http://www.tamos.net/sw/dbMetrix,dbMetrix}
Ein Open-Source-Client für das Durchsuchen von Datenbanken und die
Ausführung von SQL. Unterstützt MySQL, Oracle, PostgreSQL und mSQL.
@item @uref{http://www.multimania.com/bbrox/GtkSQL,GtkSQL}
Ein Anfrage-Werkzeug für MySQL und PostgreSQL.
@item @uref{http://dbman.linux.cz/,dbMan}
Ein Anfrage-Werkzeug, geschrieben in Perl. Benutzt DBI und Tk.
@item @uref{http://www.mysql.com/downloads/Win32/Msc201.EXE, Mascon 202}
@item @uref{http://www.mysql.com/downloads/Win32/FrMsc202.EXE, Free Mascon 202}
Mascon ist eine mächtige Win32-GUI für die Verwaltung von
MySQL-Server-Datenbanken. Die Features von Mascon beinhalten visuellen
Tabellenentwurf, Verbindungen zu mehrfachen Servern, Daten- und
Blob-Editierung von Tabellen, Sicherheitseinstellungen, SQL-Farb-Coding,
Dump-Funktionalität und vieles mehr.
@uref{http://www.scibit.com/produkte/Software/Utils/Mascon.asp,Mascon-Homepage}.
@item @uref{http://www.virtualbeer.net/dbui/,DBUI}
DBUI ist ein grafischer Gtk-Datenbank-Editor.
@item @uref{http://www.rtlabs.com/, MacSQL}
GUI für MySQL-, ODBC- und JDBC-Datenbanken für Mac OS.
@item @uref{http://www.caleb.com.au/, JRetriever}
JRetriever ist ein generisches Datenbank-Frontend-Werkzeug für
JDBC-kompatible Datenbanken, geschrieben mit Java 2. JRetriever zeigt
Datenbank- und Tabellenansichten in einem Windows-Explorer-ähnlichen
Frontend an. Der Benutzer kann Daten entweder durch Klicken auf den
Tabellen-Ordner oder durch das Zusammenstellen eigener SQL-Statements mit
dem eingebauten SQL-Editor abrufen. Das Werkzeug wurde mit Oracle 8 und
MySQL als Backend-Datenbanken getestet. Es erfordert JDK 1.3 von JavaSoft.
@item @uref{http://www.jetools.com/products/databrowser/, DataBrowser}
Der DataBrowser ist ein Datenbank- und Plattform-übergreifendes
Datenzugriffswerkzeug. Es ist benutzerfreundlicher als Werkzeuge wie SQL
Plus, psql (kommandozeilenbasierende Werkzeuge). Es ist flexibler als TOAD,
ISQL und PGAccess, die als GUIs auf eine einzige Plattform oder Datenbank
beschränkt sind.
@item @uref{http://www.intrex.net/amit/Software/, SQLC}
Die SQL Console ist eine eigenständige Java-Applikation, mit der Sie auf
ein SQL-Datenbanksystem zugreifen und SQL-Anfragen und -Aktualisierung
absetzen können. Es hat eine leicht benutzbare grafische
Benutzerschnittstelle. Die SQL Console benutzt JDBC, um sich mit dem
Datenbanksystem zu verbinden. Daher können Sie sich mit den richtigen
JDBC-Treibern mit diesem Dienstprogramm mit den beliebtesten
Datenbanksystemen verbinden.
@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_mmc.zip, MySQL MMC}
MySQL MMC ist ein GUI-Management-Werkzeug, das mit kdevelop entwickelt
wurde. Es besitzt eine sehr gute Schnittstelle, die komplett Microsoft
Enterprise Tool (für SQL Server) oder Sybase Central ähnelt. Damit können
Sie Server, Datenbanken, Tabellen, Indexe und Benutzer verwalten und
Tabellendaten in Gittern editieren, sowie SQL ausführen.
@end itemize

@cindex Web-Clients
@item Web-Clients
@itemize @minus
@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladmin-atif-1.0.tar.gz, mysqladmin-atif-1.0.tar.gz}
WWW-MySQL-Verwaltungswerkzeug für die @code{user}-, @code{db}- und
@code{host}-Tabellen. Von Tim Sailer, geändert von Atif Ghaffar
@email{aghaffar@@artemedia.ch}.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-webadmin-1.0a8-rz.tar.gz, mysql-webadmin-1.0a8-rz.tar.gz}
Ein in PHP-FI geschriebenes Werkzeug zur Verwaltung von MySQL-Datenbanken,
entfernt über das Web mit einem Web-Browser. Von Peter Kuppelwieser,
@email{peter.kuppelwieser@@kantea.it}. Aktualisiert von Wim Bonis,
@email{bonis@@kiss.de}. Wird nicht mehr gepflegt!

@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm.tar.gz, mysqladm.tar.gz}
MySQL-Web-Datenbankadministration, geschrieben in Perl. Von Tim Sailer.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysqladm-2.tar.gz, mysqladm-2.tar.gz}
Aktualisierte Version von @file{mysqladm.tar.gz}, von High Tide.

@item @uref{http://www.mysql.com/Downloads/Contrib/billowmysql.zip, billowmysql.zip}
Akualisierte Version von @file{mysqladm.tar.gz}, von Ying Gao. Sie erhalten
die neueste Version von @uref{http://civeng.com/sqldemo/, der Homepage}.

@item @uref{http://www.mysql.com/Downloads/Contrib/myadmin-0.4.tar.gz, myadmin-0.4.tar.gz}.
@item @uref{http://myadmin.cheapnet.net/, MyAdmin-Homepage}
Ein Web-basierender MySQL-Administrator von Mike Machado.

@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin_2.2.0.tar.gz,phpMyAdmin_2.2.0.tar.gz}
Ein Satz von PHP3-Skripten, um MySQL über das WWW zu administrieren.

@item @uref{http://www.phpwizard.net/Projekte/phpMyAdmin/, phpMyAdmin Homepage}
Ein PHP3-Werkzeug im Geiste von mysql-webadmin, von Tobias Ratschiller,
tobias@@dnet.it.

@item @uref{http://www.mysql.com/Downloads/Contrib/useradm.tar.gz, useradm.tar.gz}
MySQL-Administrator in PHP. Von Ofni Thomas @email{othomas@@vaidSysteme.com}.

@item @uref{http://gossamer-thread.com/perl/mysqlman/mysql.cgi, MySQLMan}
Ähnliche Funktionalität wie phpmyadmin, aber geschrieben in Perl und unter
Verwenden von HTML-Vorlagen. Von Alex Krohn.
@end itemize

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-editor.tar.gz,mysql-editor.tar.gz}
Mit diesen CGI-Skripten in Perl können Sie die Inhalte von
MySQL-Datenbanken editieren. Von Tomas Zeman.
@item
@uref{http://worldcommunity.com/openquelle/futuresql, FutureSQL Web-Datenbankadministrations-Werkzeug}.
FutureSQL von Peter F. Brown ist ein Open-Source-Web-Datenbank-Werkzeug für
die schelle Applikationsentwicklung. Geschrieben in Perl, verwendet MySQL.
Benutzt @code{DBI:DBD} und @code{CGI.pm}.

Mit FutureSQL können Sie schnell config-Dateien einrichten, um Datensätze
einer MySQL-Datenbank zu betrachten, zu editieren, zu löschen und
anderweitig zu verarbeiten. Es benutzt ein Daten-Wörterbuch,
Konfigurationsdateien und Vorlagen und erlaubt "Pre-Processing" und
"Post-Processing" von Feldern, Datensätzen und Operationen.
@end itemize

@cindex Web-Werkzeuge
@cindex Werkzeuge,, Web
@appendixsec Web-Werkzeuge

@itemize @bullet

@item @uref{http://www.mysql.com/Downloads/Contrib/mod_mysql_include_1.0.tar.gz, mod_mysql_include_1.0.tar.gz}
Apache-Modul, um HTML von MySQL-Anfragen in Ihre Seiten zu integrieren und
um Aktualisierungsanfragen auszuführen. Ursprünglich geschrieben, um ein
einfaches, schnelles Banner-Rotationssystem mit geringem Overhead zu
implementieren. Von Sasha Pachev.

@item @uref{http://htcheck.sourceforge.net, htCheck} - URL-Überprüfer mit
MySQL-Backend. Gelistete (spidered) URLs können später abgefragt werden,
wobei SQL verwendet wird, um verschiedene Sorten von Information abzurufen,
z. B. Broken Links. Geschrieben von Gabriele Bartolini.

@item @uref{http://www.odbsoft.com/cook/sources.htm}
Dieses Paket hat diverse Funktionen zum Erzeugen von HTML-Code aus einer
SQL-Tabellenstruktur und zum Erzeugen von SQL-Statements (Select, Insert,
Update, Delete) aus einem HTML-Formular. Sie können komplette
Formular-Schnittstellen zu einer SQL-Datenbank bauen (Anfrage, Hinzufügen,
Aktualisierung, Löschen), ohne jedes Programmieren! Von Marc Beneteau, @email{marc@@odbsoft.com}.

@item @uref{http://www.mysql.com/Downloads/Contrib/sqlhtml.tar.gz, sqlhtml.tar.gz}
SQL/HTML ist ein HTML-Datenbankmanager für MySQL mit @code{DBI} 1.06.

@item @uref{http://www.mysql.com/Downloads/Contrib/udmsearch-3.0.23.tar.gz, UdmSearch 3.0.23 (stabile Version)}.
@c German FIX removed comma (",") to make description work inside uref
@item @uref{http://www.mysql.com/Downloads/Contrib/mnogosearch-3.1.12.tar.gz, mnogosearch 3.1.12 (Entwicklungs- aber empfohlene Version)}.
@item @uref{http://search.mnoGo.ru, UdmSearch-Homepage}
Eine SQL-basierende Suchmaschine fürs Internet. Von Alexander I. Barkov @email{bar@@izhcom.ru}.

@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.doc, wmtcl.doc}.
@item @uref{http://www.mysql.com/Downloads/Contrib/wmtcl.lex, wmtcl.lex}
Hiermit können Sie HTML-Dateien mit Einfügungen von Tcl-Code schreiben. Von @email{vvs@@scil.npi.msu.su}.

@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.lsm, www-sql-0.5.7.lsm}.
@item @uref{http://www.mysql.com/Downloads/Contrib/www-sql-0.5.7.tar.gz, www-sql-0.5.7.tar.gz}
Ein CGI-Programm, das eine HTML-Datei mit speziellen Tags parst, die Tags
selbst parst und Daten aus einer MySQL-Datenbank einfügt.

@item @uref{http://www.mysql.com/Downloads/Contrib/genquery.zip, genquery.zip}
Perl-SQL-Datenbankschnittstellenpaket für HTML.

@item @uref{http://www.mysql.com/Downloads/Contrib/cgi++-0.8.tar.gz, cgi++-0.8.tar.gz}
Ein Makro-Prozessor, um leicht CGI/Datenbank-Programme in C++ zu schreiben. Von Sasha Pachev.

@item  @uref{http://www.mysql.com/Downloads/Contrib/webboard-1.0.zip, WebBoard 1.0}
EU-Industries Internet-Message-Board.

@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz, DBIx-TextIndex-0.02.tar.gz}
Volltextsuche mit Perl auf @code{BLOB}/@code{TEXT}-Spalten. Von Daniel Koch.
@end itemize

@cindex Werkzeuge, Benchmark-
@cindex Benchmark, Werkzeuge
@appendixsec Performance-Benchmark-Werkzeuge

@itemize @bullet
@item @uref{http://www.mysql.com/downloads/super-smack/super-smack-1.0.tar.gz,
 super-smack}
Multi-Threaded Benchmark-Werkzeug für MySQL und @strong{PostgreSQL}.
Geschrieben in C++. Leicht zu erweitern für die Unterstützung anderer
Datenbanken, die C/C++-Client-Bibliotheken haben. Von Sasha Pachev.
@end itemize

@cindex Werkzeuge, Authentifizierung
@cindex Authentifizierungswerkzeuge
@appendixsec Authentifizierungswerkzeuge

@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/ascend-radius-mysql-0.7.2.patch.gz,ascend-radius-mysql-0.7.2.patch.gz}
Das ist ein Authentifizierungs- und Logging-Patch, der MySQL für Ascend-Radius benutzt. Von @email{takeshi@@SoftAgency.co.jp}.

@item @uref{http://www.mysql.com/Downloads/Contrib/icradius-0.10.tar.gz, icradius 0.10}
@uref{http://www.mysql.com/Downloads/Contrib/icradius.README, icradius readme-Datei}.

@item @uref{http://www.mysql.com/Downloads/Contrib/checkpassword-0.81-mysql-0.6.6.patch.gz,
checkpassword-0.81-mysql-0.6.6.patch.gz}
MySQL-Authentifizierungs-Patch für QMAIL und checkpassword. Diese sind
nützlich für die Benutzerverwaltung (mail, pop account) von MySQL.
Von @email{takeshi@@SoftAgency.co.jp}.

@item @uref{http://www.mysql.com/Downloads/Contrib/jradius-diff.gz, jradius-diff.gz}
MySQL-Unterstützung für Livingston's Radius 2.01. Authentifizierung und
Abrechnung. Von Jose de Leon, @email{jdl@@thevision.net}.

@item @uref{http://www.mysql.com/Downloads/Contrib/mod_auth_mysql-2.20.tar.gz, mod_auth_mysql-2.20.tar.gz}
Apache-Authentifizierungsmodul für MySQL. Von Zeev Suraski,
@email{bourbon@@netvision.net.il}.

@c @strong{Bitte} registrieren Sie dieses Modul unter:
@c @url{http://bourbon.netvision.net.il/mysql/mod_auth_mysql/register.html}.
@c Die Registrierungsinformationen werden nur für statistische Zwecke
@c benutzt und fördern die Weiterentwicklung dieses Moduls!

@item @uref{http://www.mysql.com/Downloads/Contrib/mod_log_mysql-1.05.tar.gz, mod_log_mysql-1.05.tar.gz}
MySQL-Loggingmodul für Apache. Von Zeev Suraski,
@email{bourbon@@netvision.net.il}.

@item @uref{http://www.mysql.com/Downloads/Contrib/mypasswd-2.0.tar.gz, mypasswd-2.0.tar.gz}
Zusatz für @code{mod_auth_mysql}. Das kleine Werzeug ermöglicht Ihnen,
Benutzerdatensätze hinzuzufügen oder zu ändern, wobei Gruppen- und / oder
Passwort-Einträge in MySQL-Tabellen gespeichert werden. Von Harry
Brueckner, @email{brueckner@@respublica.de}.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd.README, mysql-passwd.README}.
@item @uref{http://www.mysql.com/Downloads/Contrib/mysql-passwd-1.2.tar.gz, mysql-passwd-1.2.tar.gz}
Zusatz für @code{mod_auth_mysql}. Ein System aus zwei Bestandteilen zur
Benutzung mit @code{mod_auth_mysql}.

@item @uref{http://www.mysql.com/Downloads/Contrib/pam_mysql.tar.gz, pam_mysql.tar.gz}
Dieses Modul authentifiziert Benutzer via @code{pam}, mit MySQL.

@item @uref{http://www.mysql.com/Downloads/Contrib/nsapi_auth_mysql.tar, nsapi_auth_mysql.tar}
Netscape-Webserver-API- (NSAPI) Funktionen, um (BASIC) Benutzer gegen
MySQL-Tabellen zu authentifizieren. Von Yuan John Jiang.

@item @uref{http://www.mysql.com/Downloads/Contrib/qmail-1.03-mysql-0.6.6.patch.gz,qmail-1.03-mysql-0.6.6.patch.gz}
Patch für qmail, um Benutzer einer MySQL-Tabelle zu authentifizieren.
Von @email{takeshi@@SoftAgency.co.jp}.

@item @uref{http://www.mysql.com/Downloads/Contrib/proftpd-1.2.0rc2-fix-mysql.patch, proftpd-1.2.0rc2-fix-mysql.patch}
Patch für proftpd1.2.0rc2. Von @email{takeshi@@SoftAgency.co.jp}.

@item @uref{http://www.mysql.com/Downloads/Contrib/pwcheck_mysql-0.1.tar.gz,pwcheck_mysql-0.1.tar.gz}
Ein Authentifizierungsmodul für den Cyrus-IMAP-Server. Von Aaron Newsome.


@end itemize

@cindex Konverter
@appendixsec Konverter

@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/mssql2mysql.txt, mssql2mysql.txt}
Konverter von MS-SQL zu MySQL. Von Michael Kofler.
@uref{http://www.kofler.cc/mysql/mssql2mysql.html, mssql2mysql Homepage}.

@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.14.tar.gz, dbf2mysql-1.14.tar.gz}
Konvertiert zwischen @file{.dbf}-Dateien und MySQL-Tabellen. Von Maarten
Boekhold (@email{boekhold@@cindy.et.tudelft.nl}), William Volkman und
Michael Widenius. Dieser Konverter schließt rudimentäre Unterstützung (nur
lesen) für MEMO-Felder ein.

@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql-1.13.tgz, dbf2mysql-1.13.tgz}
Konvertiert zwischen @file{.dbf}-Dateien und MySQL-Tabellen. Von Maarten
Boekhold, @email{boekhold@@cindy.et.tudelft.nl} und Michael Widenius.
Dieser Konverter kann keine MEMO-Felder handhaben.

@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2mysql.zip, dbf2mysql.zip}
Konvertiert zwischen FoxPro-@file{.dbf}-Dateien und MySQL-Tabellen unter Windows.
Von Alexunder Eltsyn, @email{ae@@nica.ru} oder @email{ae@@usa.net}.

@item @uref{http://www.mysql.com/Downloads/Contrib/dbf2sql.zip, dbf2sql.zip}
Kurzes, einfaches Programm, dass Ihnen bei der Überführung Ihrer Daten von
Foxpro-Tabellen in MySQL-Tabellen helfen kann. Von Danko Josic.

@item @uref{http://www.mysql.com/Downloads/Contrib/dump2h-1.20.gz, dump2h-1.20.gz}
Konvertiert von einer @code{mysqldump}-Ausgabe in eine C-Header-Datei. Von
Harry Brueckner, @email{brueckner@@mail.respublica.de}.

@item @uref{http://www.mysql.com/Downloads/Contrib/exportsql.txt, exportsql.txt}
Ein Skript, das @code{access_to_mysql.txt} ähnelt, ausser dass dieses voll
konfigurierbar ist, eine bessere Typumwandlung hat (inklusive Erkennung von
@code{TIMESTAMP}-Feldern), bei der Konvertierung Warnungen und Vorschläge
bereit stellt, Anführungszeichen, @strong{alle} Sonderzeichen in Text und
Binärdaten erkennt usw. Es konvertiert ausserdem nach @code{mSQL} Version 1
und 2, und kostet nichts. Siehe @uref{http://www.cynergi.net/exportsql/}
wegen der neuesten Version. Von Pedro Freire, @email{Support@@cynergi.net}.
@strong{HINWEIS:} Funktioniert nicht mit Access 2!

@item @uref{http://www.mysql.com/Downloads/Contrib/access_to_mysql.txt, access_to_mysql.txt}
Kopieren Sie diese Funktion in ein Access-Modul einer Datenbank, die die
Tabellen enthält, die Sie exportieren wollen. Siehe auch @code{exportsql}.
Von Brian Andrews. @strong{HINWEIS:} Funktioniert nicht mit Access 2!

@item @uref{http://www.mysql.com/Downloads/Contrib/importsql.txt, importsql.txt}
Ein Skript, das genau das Gegenteil von @code{exportsql.txt} macht. Es
importiert Daten von MySQL in eine Access-Datenbank via ODBC. Das ist sehr
handlich, wenn es mit exportsql kombiniert wird, weil Sie damit Access für
das Datenbank-Design und die -Administration verwenden können und das
Getane dann mit Ihrem MySQL-Server synchronisieren können. Siehe
@uref{http://www.netdive.com/freebies/importsql/} wegen Aktualisierungen.
Geschrieben von Laurent Bossavit von NetDIVE.
@strong{HINWEIS:} Funktioniert nicht mit Access 2!

@item @uref{http://www.mysql.com/Downloads/Contrib/mdatabase2sql.bas,
mdatabase2sql.bas}
Konverter von Access97 nach MySQL von Moshe Gurvich.

@item
@uref{http://www.mysql.com/Downloads/Contrib/msql2mysqlWrapper-1.0.tgz,
msql2mysqlWrapper 1.0}
Ein C-Wrapper von @code{mSQL} nach MySQL. Von @email{alfred@@sb.net}

@item @uref{http://www.mysql.com/Downloads/Contrib/sqlconv.pl, sqlconv.pl}
Ein einfaches Skript, das zum Kopieren von Feldern von einer MySQL-Tabelle
in eine andere im Massenverfahren benutzt werden kann. Im Wesentlichen
können Sie @code{mysqldump} laufen lassen und die Ausgabe an das
@code{sqlconv.pl}-Skript übergeben. Das Skript parst die
@code{mysqldump}-Ausgabe und ordnet die Felder neu, so dass sie in die neue
Tabelle eingefügt werden können. Ein Beispiel hierfür ist, dass Sie eine
neue Tabelle für eine andere Site, an der Sie arbeiten, erstellen wollen,
die Tabelle jedoch ein bisschen anders ist (also die Felder in anderer
Reihenfolge hat usw.). Von Steve Shreeve.
@item @uref{http://www.mysql.com/Downloads/Contrib/oracledump oderacledump}
Perl-Programm, um Oracle-Datenbanken nach MySQL zu konvertieren. Hat
dasselbe Ausgabeformat wie mysqldump. Von Johan Andersson.

@item @uref{http://www.mysql.com/Downloads/Contrib/excel2mysql.pl, excel2mysql.pl}
Perl-Programm, um Excel-Tabellen in eine MySQL-Datenbank zu importieren.
Von Stephen Hurd @email{shurd@@sk.sympatico.ca}

@item @uref{http://www.mysql.com/Downloads/Contrib/T2S_100.ZIP, T2S_100.ZIP}.
Windows-Programm zum Konvertieren von Textdateien in MySQL-Datenbanken. Von
Asaf Azulay.

@end itemize

@appendixsec MySQL mit anderen Produkten benutzen

@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/emacs-sql-mode.tar.gz, emacs-sql-mode.tar.gz}
Raw-Portierung eines SQL-Modus für XEmacs. Unterstützt Vervollständigung.
Original von Peter D. Pezaris @email{pez@@atlantic2.sbi.com} und teilweise
MySQL-Portierung von David Axmark.

@item @uref{http://www.mysql.com/downloads/Win32/myaccess97_1_4.zip, MyAccess97 1.4}.
@item @uref{http://www.mysql.com/downloads/Win32/myaccess2000_1_4.zip, MyAccess2000 1.4}.

MyAccess ist ein Add-In für MS-Access 97/2000, mit dem MySQL-Datenbanken
innerhalb von Access verwaltet werden können. Hauptfunktionen sind:
@itemize @minus
@item Erzeugen und Ändern von Tabellen
@item Anfragen an MySQL ausführen
@item ''Erzeugen von Tabellen-Skripten'' von MySQL
@item Importieren / Exportieren von Tabellen aus Access nach MySQL und umgekehrt
@item Änderungen mitschreiben (Log)
@item Einen Datenbank-Definitionsbericht anzeigen
@end itemize

Geschrieben von Hubertus Hiden. @uref{http://www.accessmysql.com, MyAccess-Homepage}.

@item @uref{http://www.mysql.com/Downloads/Contrib/radius-0.3.tar.gz, radius-0.3.tar.gz}
Patches für @code{radiusd}, damit es MySQL unterstützt. Von Wim Bonis,
@email{bonis@@kiss.de}.
@end itemize

@cindex Werkzeuge, nützliche
@appendixsec Nützliche Werkzeuge

@itemize @bullet
@item @uref{http://worldcommunity.com/opensource/utilities/mysql_backup.html, MySQL-Datensicherung}.

Ein Datensicherungsskript für MySQL. Von Peter F. Brown.

@item @uref{http://www.mysql.com/Downloads/Contrib/mytop, mytop}
@item @uref{http://public.yahoo.com/~jzawodn/mytop/, mytop Homepage}
mytop ist ein Perl-Programm, mit dem Sie MySQL-Server beobachten können,
indem Sie aktive Threads, Anfragen und Server-Performance über alles
betrachten. Von Jeremy D. Zawodny.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_watchdog.pl, mysql_watchdog.pl}
Den MySQL-Daemon auf mögliche Blockierungen überwachen. Von Yermo Lamers,
@email{yml@@yml.com}.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysqltop.tar.gz, mysqltop.tar.gz}
Sendet eine Anfrage in einem festen Zeitintervall an den Server und zeigt
die Ergebnistabelle. Von Thomas Wana.
@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tar.gz,mysql_structure_dumper.tar.gz}
Gibt die Struktur aller Tabellen in einer Datenbank aus. Von Thomas Wana.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_structure_dumper.tgz, structure_dumper.tgz}
Gibt die Struktur aller Tabellen in einer Datenbank aus. Von Thomas Wana.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysqlsync, mysqlsync-1.0-alpha.tar.gz}.
Ein Perl-Skript, um entfernte Kopien einer MySQL-Datenbank mit einer
zentralen Master-Kopie synchronisiert zu halten. Von Mark Jeftovic. @email{markjr@@easydns.com}.

@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLTutor-0.2.tar.gz, MySQLTutor}.
MySQLTutor. Ein MySQL-Tutorial für Anfänger.

@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB.zip, MySQLDB.zip}
Eine COM-Bibliothek für MySQL von Alok Singh.
@item @uref{http://www.mysql.com/Downloads/Contrib/MySQLDB-readme.html, MySQLDB-readme.html}.

@item @uref{http://www.mysql.com/Downloads/Contrib/mysql_replicate.pl, mysql_replicate.pl}
Perl-Programm, das Replikation handhabt. Von @email{elble@@icculus.nsg.nwu.edu}

@item @uref{http://www.mysql.com/Downloads/Contrib/DBIx-TextIndex-0.02.tar.gz, DBIx-TextIndex-0.02.tar.gz}
Perl-Skript, das umgekehrte Indexierung für Textsuchen benutzt. Von Daniel
Koch.

@item @uref{http://www.mysql.com/Downloads/Contrib/dbcheck, dbcheck}
Perl-Skript, das eine Datensicherung der Tabellen macht, bevor isamchk
darauf laufen gelassen wird. Von Elizabeth.

@item @uref{http://www.mysql.com/Downloads/Contrib/mybackup}.
@item @uref{http://www.mswanson.com/mybackup, mybackup-Homepage}
Wrapper für mysqldump, um alle Datenbanken zu sichern. Von Marc Swanson.

@item @uref{http://www.mysql.com/Downloads/Contrib/mdu.pl.gz,mdu.pl.gz}
Gibt die Speicherbenutzung einer MySQL-Datenbank aus.
@end itemize

@cindex RPMs, für gebräuchliche Werkzeuge
@cindex Werkzeuge, RPMs für
@appendixsec RPMs für gebräuchliche Werkzeuge (die meisten sind für RedHat 6.1)

@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Data-ShowTable-3.3-2.i386.rpm,perl-Data-ShowTable-3.3-2.i386.rpm}
@item @uref{http://www.mysql.com/Downloads/Contrib/perl-Msql-Mysql-modules-1.2210-2.i386.rpm,perl-Msql-Mysql-modules-1.2210-2.i386.rpm}
@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-3.0.13-1.i386.rpm,php-pg-3.0.13-1.i386.rpm}
@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-manual-3.0.13-1.i386.rpm,php-pg-manual-3.0.13-1.i386.rpm}
@item @uref{http://www.mysql.com/Downloads/Contrib/php-pg-mysql-3.0.13-1.i386.rpm,php-pg-mysql-3.0.13-1.i386.rpm}
@item @uref{http://www.mysql.com/Downloads/Contrib/phpMyAdmin-2.0.5-1.noarch.rpm,phpMyAdmin-2.0.5-1.noarch.rpm}
@end itemize

@cindex Funktionen, nützliche
@appendixsec Nützliche Funktionen
@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/mysnprintf.c,mysnprintf.c}
sprintf()-Funktion für SQL-Anfragen, die Blobs escapen kann. Von Chunhua Liu.
@end itemize

@appendixsec Windows-Programme
@itemize @bullet
@item @uref{http://www.mysql.com/Downloads/Contrib/LaunchMySQL.zip, LaunchMySQL.zip}
Das Programm startet den MySQL-Server, fährt ihn herunter und gibt
Status-Informationen aus. Von Bill Thompson
@end itemize

@appendixsec Nicht kategorisiert

@itemize @bullet

@item @uref{http://www.mysql.com/Downloads/Contrib/findres.pl, findres.pl}
Findet reservierte Wörter in Tabellen. Von Nem W Schlecht.

@item @uref{http://www.mysql.com/Downloads/Contrib/handicap.tar.gz, handicap.tar.gz}
Performance-Handicapping-System für Yachten. Benutzt PHP. Von
@email{rhill@@stobyn.ml.org}.

@item @uref{http://www.mysql.com/Downloads/Contrib/hylalog-1.0.tar.gz, hylalog-1.0.tar.gz}
Speichert ausgehende @code{hylafax}-Faxe in einer MySQL-Datenbank. Von
Sinisa Milivojevic, @email{sinisa@@mysql.com}.

@item @uref{http://www.mysql.com/Downloads/Contrib/mrtg-mysql-1.0.tar.gz, mrtg-mysql-1.0.tar.gz}
MySQL-Status-Ausgabe mit MRTG, von Luuk de Boer, @email{luuk@@wxs.nl}.

@item @uref{http://www.mysql.com/Downloads/Contrib/wuftpd-2.4.2.18-mysql_Support.2.tar.gz, wuftpd-2.4.2.18-mysql_Support.2.tar.gz}
Patches, um Loggen nach MySQL für WU-ftpd hinzuzufügen. Von Zeev Suraski,
@email{bourbon@@netvision.net.il}.

@item @uref{http://www.mysql.com/Downloads/Contrib/wu-ftpd-2.6.0-mysql.4.tar.gz,wu-ftpd-2.6.0-mysql.4.tar.gz}
Patches, um Loggen nach MySQL für WU-ftpd 2.6.0 hinzuzufügen. Von
@email{takeshi@@SoftAgency.co.jp}, basierend auf den
Zeev-Suraski-wuftpd-Patches.

@item @uref{http://www.mysql.com/Downloads/Contrib/Old-Versions, Alte Versionen}
Frühere Versionen von Dingen in diesen Listen, an denen Sie wahrscheinlich
nicht interessiert sind.
@end itemize
@page




@node Credits, News, Contrib, Top
@c German node Danksagungen
@appendix Danksagungen

@cindex Entwickler, Auflistung

Dieser Anhang listet die Entwickler, Kontributoren und Unterstützer auf,
die mitgeholfen haben, dass MySQL das wird, was es heute ist.



@menu
* Developers::                  
* Contributors::                
* Supporters::                  
@end menu

@node Developers, Contributors, Credits, Credits
@c German node Entwickler
@appendixsec Entwickler bei MySQL AB

Hier sind die Entwickler, die von @code{MySQL AB} angestellt wurden, um an 
@code{MySQL} zu arbeiten, ungefähr in der Reihenfolge ihres Eintritts. 
Neben dem Namen wird aufgelistet, für welche Teilaufgaben der Entwickler 
verantwortlich ist oder welche Leistungen er erbracht hat.

@table @asis
@item Michael (Monty) Widenius
Schrieb folgende Bestandteile von MySQL:
@itemize @bullet
@item
Den gesamten Haupt-Code in @code{mysqld}.
@item
Neue Funktionen für die Zeichenketten-Bibliothek.
@item
Das meiste der @code{mysys}-Bibliothek.
@item
Die @code{ISAM}- und @code{MyISAM}-Bibliotheken (B-Baum-Index-Datei-Handler
mit Index-Komprimierung und verschiedenen Datensatzformaten).
@item
Die @code{HEAP}-Bibliothek. Ein Speicher-Tabellensystem mit unserem
überragenden komplett dynamischen Hashing. In Gebrauch seit 1981 und
veröffentlicht um 1984.
@item
Das @code{replace}-Programm (ansehen, es ist COOL!).
@item
@strong{MyODBC}, den ODBC-Treiber für Windows95.
@item
Behob Bugs in MIT-pThread, um sie für MySQL zum Laufen zu bringen, sowie
Unireg, ein curses-basierendes Applikationswerkzeug vielen Utilities.
@item
Portierung von @code{mSQL}-Werkzeugen wie @code{msqlperl},
@code{DBD}/@code{DBI} und @code{db2mysql}.
@item
Das meiste von Crash-me und die Grundlage für die MySQL-Benchmarks.
@end itemize

@item David Axmark
@itemize @bullet
@item
Koordinator und ursprünglicher Haupt-Schreiber des
@strong{Referenzhandbuchs}, inklusive Verbesserungen von @code{texi2HTML}.
@item
Automatische Website-Aktualisierung des Handbuchs.
@item
Ursprüngliche Autoconf-, Automake- und Libtool-Unterstützung.
@item
Den Lizensierungs-Kram.
@item
Teile all der Textdateien. (Heutzutage ist nur noch die @file{README}
übrig. Der Rest befindet sich im Handbuch.)
@item
Viel Testen neuer Features.
@item
Unser ``kostenloser'' Inhouse-Software-Anwalt.
@item
Derjenige, der die Mailing-Liste wartet (und nie die Zeit hatte, es richtig
zu machen ...)
@item
Unser Original-Portabilitätscode (jetzt mehr als 10 Jahre alt). Heutzutage
sind nur noch Teile von @code{mysys} übrig.
@item
Jemand, den Monty mitten in der Nacht anrufen kann, wenn er gerade das neue
Feature zum Laufen gebracht hat.
@end itemize

@item Jani Tolonen
@itemize @bullet
@item
@code{mysqlimport}
@item
Etliche Erweiterungen zum @code{mysql}-Client.
@item
@code{Prozeduranalyse()}
@end itemize

@item Sinisa Milivojevic
@itemize @bullet
@item
Kompression (mit @code{zlib}) im Client-Server-Protokoll.
@item
Perfektes Hashing für die lexikalische Analyse-Phase.
@item
Den MySQLGUI-Client.
@item
Derjenige, der mysql++ wartet.
@end itemize

@item Tonu Samuel
@itemize @bullet
@item
Unser Sicherheitsexperte.
@item
Vio-Schnittstelle (die Grundlage für das verschlüsselte Client-Server-Protokoll).
@item
MySQL-Dateisystem (eine Art, MySQL-Datenbanken als Dateien und
Verzeichnisse zu benutzen).
@item
Den CASE-Ausdruck.
@item
Die MD5()- und COALESCE()-Funktionen.
@item
@code{RAID}-Unterstützung für @code{MyISAM}-Tabellen.
@end itemize

@item Sasha Pachev
@itemize @bullet
@item
Replikation.
@item
@code{SHOW CREATE TABLE}.
@item
mod_mysql_include
@item
cgi++
@item
mysql-bench
@end itemize

@item Matt Wagner
@itemize @bullet
@item
MySQL-Test-Suite.
@item
Unser Webmaster.
@end itemize

@item Miguel Solorzano
@itemize @bullet
@item
Winmysqladmin.
@end itemize

@item Timothy Smith
@itemize @bullet
@item
Dynamische Zeichen-Unterstützung.
@item
Verantwortlich für MySQL-configure.
@end itemize

@item Sergei Golubchik
@itemize @bullet
@item
Volltextsuche.
@item
Fügte Schlüssel zur @code{MERGE}-Bibliothek hinzu.
@end itemize

@item Jeremy Cole
@itemize @bullet
@item

Korrekturlesen und Editieren dieses netten Handbuchs.
@item
@code{ALTER TABLE ... ORDER BY ...}.
@item
@code{UPDATE ... ORDER BY ...}.
@item
@code{DELETE ... ORDER BY ...}.
@end itemize

@item John Dean
@itemize @bullet
@item
Den MySQL-GUI-Client.
@end itemize

@item Indrek Siitan
@itemize @bullet
@item
Designer / Programmierer unserer Web-Schnittstelle.
@end itemize
@end table

Folgende Nicht-Entwickler arbeiten ebenfalls bei oder zusammen mit MySQL
AB:

@table @asis
@item
Hans Kierkegaard - verantwortlich für die MySQL-Lizenz-Handhabung.
@item
Antti Halonen - Vertriebsleiter.
@item
Jonas Norrman - Beantwortet Lizensierungsfrage, die an
@email{info@@mysql.com} geschickt werden.
@item
Erik Granberg - bedient MySQL-Partner (und eine Menge sonstiger Kram).
@item
Allan Larsson (der BOSS für TCX DataKonsult AB).
@end table


@node Contributors, Supporters, Developers, Credits
@c German node Kontributoren
@appendixsec Kontributoren zu MySQL

@cindex Kontributoren, Auflistung

Während @code{MySQL AB} das gesammte Copyright für den @code{MySQL Server}
und das @code{MySQL manual} besitzt, möchten wir hier diejenigen Menschen
nennen, die das Ein oder Andere zur @code{MySQL Distribution} beigetragen
haben. Die Kontributoren sind in eher zufälliger Reihenfolge aufgeführt:

@table @asis
@item Paul DuBois
Hilft mit, das Referenzhandbuch korrekt und verständlich zu machen. Das
beinhaltet, Montys und Davids Englischversuche in das Englisch zu
übertragen, das andere Leute kennen.
@item Gianmassimo Vigazzola @email{qwerg@@mbox.vol.it} oder @email{qwerg@@tin.it}
Die ursprüngliche Portierung auf Win32/NT.
@item Kim Aldale
Half, Montys und Davids frühe Englischversuche ins Englische umzuschreiben.
@item Per Eric Olsson
Mehr oder weniger konstruktive Kritik und Testen des dynamischen
Datensatzformats.
@item Irena Pancirov @email{irena@@mail.yacc.it}
Win32-Portierung mit dem Borland-Compiler. @code{mysqlshutdown.exe} und
@code{mysqlwatch.exe}
@item David J. Hughes
Er bemühte sich, eine Shareware-SQL-Datenbank herzustellen. Wir bei TcX
fingen mit @code{mSQL} an, fanden aber, dass es unsere Bedürfnisse nicht
befriedigen könne, daher schrieben wir stattdessen eine SQL-Schnittstelle
zu unserem Applikation-Builder Unireg.  @code{mysqladmin} und @code{mysql}
sind Programme, die stark von ihren @code{mSQL}-Pendants beeinflusst sind.
Wir haben uns große Mühe gegeben, die MySQL-Syntax zu einer Obermenge von
@code{mSQL} zu machen. Viele API-Ideen sind von @code{mSQL} entliehen,
damit es einfach ist, kostenlose @code{mSQL}-Programme nach MySQL zu
portieren. MySQL enthält keinen Code von @code{mSQL}. Zwei Dateien in der
Distribution (@file{client/insert_test.c} und @file{client/select_test.c})
basieren auf den entsprechenden (keinem Copyright unterliegenden) Dateien
in der @code{mSQL}-Distribution, sind aber als Beispiele abgeändert, die
die notwendigen Änderungen aufzeigen, wenn man Code von @code{mSQL} nach
MySQL konvertiert. (@code{mSQL} unterliegt dem Copyright von David J. Hughes.)
@item Fred Fish
Seine exzellente C-Debugging- und Trace-Bibliothek. Monty hat eine Reihe
kleinerer Verbesserungen an der Bibliothek vorgenommen (Geschwindigkeit und
zusätzliche Optionen).
@item Richard A. O'Keefe
Seine Public-Domain-Zeichenketten-Bibliothek.
@item Henry Spencer
Seine Regex-Bibliothek, benutzt bei @code{WHERE spalte REGEXP regexp}.
@item Free Software Foundation
Von ihnen haben wir einen exzellenten Compiler (@code{gcc}), die
@code{libc}-Bibliothek (aus der wir @file{strto.c} entliehen haben, damit
einiger Code unter Linux funktioniert), und die @code{readline}-Bibliothek
(für den @code{mysql}-Client).
@item Free Software Foundation und das XEmacs-Entwicklungsteam
Ihr großartiger Editor, der für fast jeden Artikeltext bei TcX/MySQL
AB/detron benutzt wird.
@item Patrick Lynch
Für seine Hilfe bei @code{http://www.mysql.com/}.
@item Fred Lindberg
Er half, qmail aufzusetzen, um die MySQL Mailing-Liste zu handhaben, und
für seine unglaubliche Unterstützung bei der Verwaltung der MySQL
Mailing-Listen.
@item Igor Romanenko @email{igor@@frog.kiev.ua}
@code{mysqldump} (vormals @code{msqldump}, aber portiert und verbessert von
Monty).
@item Yuri Dario
Er unterhält die MySQL-OS/2-Portierung und baut sie aus.
@item Tim Bunce, Alligator Descartes
Für die @code{DBD}-(Perl)-Schnittstelle.
@item Tim Bunce
Autor von @code{mysqlhotcopy}.
@item Andreas Koenig @email{a.koenig@@mind.de}
Für die Perl-Schnittstelle zu MySQL.
@item Eugene Chan @email{eugene@@acenet.com.sg}
Für den Port von PHP zu MySQL.
@item Michael J. Miller Jr. @email{mke@@terrapin.turbolift.com}
Er schrieb das erste MySQL-Handbuch, und nahm etliche Bereinigungen der
Rechtschreibung / Sprache für die FAQ vor (aus dieser entstand vor langer
Zeit das MySQL-Handbuch).
@item Yan Cailin
Erster Übersetzer des MySQL-Referenzhandbuch in vereinfachtes Chinesisch,
Anfang 2000, auf der die Big5- und HK-kodierten Versionen
(@uref{http://mysql.hitstar.com, mysql.hitstar.com}) basieren.
@uref{http://linuxdb.yeah.net, Private Homepage bei linuxdb.yeah.net}.
@item Giovanni Maruzzelli @email{maruzz@@matrice.it}
Für die Portierung von iODBC (Unix ODBC).
@item Chris Provenzano
Portierbarer Benutzerebene-pThread. Aus dem Copyright: Dieses Produkt
beinhaltet Software, die von Chris Provenzano, University of California,
Berkeley und Kontributoren entwickelt wurde. Momentan benutzen wir Version
1_60_beta6, die von Monty gepatcht wurde (siehe @file{with-pThread/Changes-mysql}).
@item Xavier Leroy @email{Xavier.Leroy@@inria.fr}
Der Autor von LinuxThread (benutzt von MySQL unter Linux).
@item Zarko Mocnik @email{zarko.mocnik@@dem.si}
Sortieren für slowenische Sprache und die @file{cset.tar.gz}-Module, die es
vereinfachen, andere Zeichensätze hinzuzufügen.
@item "TAMITO" @email{tommy@@valley.ne.jp}
Die @code{_MB}-Zeichensatz-Makros und die ujis- und sjis-Zeichensätze.
@item Joshua Chamas @email{joshua@@chamas.com}
Grundlage für gleichzeitige Einfügeoperationen, erweiterte Datums-Syntax,
Debuggen unter NT und Antworten in der MySQL-Mailing-Liste.
@item Yves Carlier @email{Yves.Carlier@@rug.ac.be}
@code{mysqlaccess}, ein Programm, das die Zugriffsrechte für einen Benutzer
anzeigt.
@item Rhys Stefan @email{rhys@@wales.com} (und GWE Technologies Limited)
Für JDBC, ein Modul, um Daten aus MySQL mit einem Java-Client zu
extrahieren.
@item Dr. Xiaokun Kelvin ZHU @email{X.Zhu@@brad.ac.uk}
Weiterentwicklung der JDBC-Treiber und anderer MySQL-bezogener
Java-Werkzeuge.
@item James Cooper @email{pixel@@organic.com}
Aufsetzen eines durchsuchbaren Mailing-Listen-Archivs auf seiner Site.
@item Rick Mehalick @email{Rick_Mehalick@@i-o.com}
Für @code{xmysql}, einen grafischen X-Client für MySQL.
@item Doug Sisk @email{sisk@@wix.com}
Er stellt RPM-Pakete von MySQL für RedHat Linux bereit.
@item Diemund Alexunder V. @email{axeld@@vial.ethz.ch}
Er stelle RPM-Pakete von MySQL für RedHat Linux-Alpha bereit.
@item Antoni Pamies Olive @email{toni@@readysoft.es}
Er stellt RPM-Versionen vieler MySQL-Clients für Intel und SPARC bereit.
@item Jay Bloodworth @email{jay@@pathways.sde.state.sc.us}
Er stellte RPM-Versionen für MySQL-Version 3.21 bereit.
@item Jochen Wiedmann @email{wiedmann@@neckar-alb.de}
Für die Wartung der Perl-@code{DBD::mysql}-Module.
@item Therrien Gilbert @email{gilbert@@ican.net}, Jean-Marc Pouyot @email{jmp@@scalaire.fr}
Französische Fehlermeldungen.
@item Petr snajdr, @email{snajdr@@pvt.net}
Tschechische Fehlermeldungen.
@item Jaroslaw Lewundowski @email{jotel@@itnet.com.pl}
Polnische Fehlermeldungen.
@item Miguel Angel Fernundez Roiz
Spanische Fehlermeldungen.
@item Roy-Magne Mo @email{rmo@@www.hivolda.no}
Norwegische Fehlermeldungen und Testen von Version 3.21.#.
@item Timur I. Bakeyev @email{root@@timur.tatarstan.ru}
Russische Fehlermeldungen.
@item @email{brenno@@dewinter.com} && Filippo Grassilli @email{phil@@hyppo.com}
Italienische Fehlermeldungen.
@item Dirk Munzinger @email{dirk@@trinity.saar.de}
Deutsche Fehlermeldungen.
@item Billik Stefan @email{billik@@sun.uniag.sk}
Slowakische Fehlermeldungen.
@item Stefan Saroiu @email{tzoompy@@cs.washington.edu}
Rumänische Fehlermeldungen.
@item Peter Feher
Ungarische Fehlermeldungen.
@item Roberto M. Serqueira
Portugiesische Fehlermeldungen.
@item Carsten H. Pedersen
Dänische Fehlermeldungen
@item David Sacerdote @email{davids@@secnet.com}
Knowhow für die Sicherheitsprüfung von DNS-Hostnamen.
@item Wei-Jou Chen @email{jou@@nematic.ieo.nctu.edu.tw}
Unterstützung für chinesisch(BIG5)-Zeichen.
@item  Wei He @email{hewei@@mail.ied.ac.cn}
Viel Funktionalität für den chinesischen (GBK-) Zeichensatz.
@item Zeev Suraski @email{bourbon@@netvision.net.il}
@code{FROM_UNIXTIME()}-Zeitformatierung, @code{ENCRYPT()}-Funktionen und
@code{bison}-Ratgeber.
Aktives Mitglied der Mailing-Liste.
@item Luuk de Boer @email{luuk@@wxs.nl}
Portierte (und erweiterte) die Benchmark-Suite für @code{DBI}/@code{DBD}.
War eine große Hilfe bei @code{Crash-me} und beim Laufenlassen von
Benchmarks. Einige neue Datumsfunktionen. Das mysql_setpermissions-Skript.
@item Jay Flaherty @email{fty@@mediapulse.com}
Große Teile des Perl-@code{DBI}/@code{DBD}-Abschnitts im Handbuch.
@item Paul Southworth @email{pauls@@etext.org}, Ray Loyzaga @email{yar@@cs.su.oz.au}
Korrekturlesen des Referenzhandbuchs.
@item Alexis Mikhailov @email{root@@medinf.chuvashia.su}
Benutzerdefinierte Funktionen (UDFs); @code{CREATE FUNCTION} und
@code{DROP FUNCTION}.
@item Andreas F. Bobak @email{bobak@@relog.ch}
Die @code{AGGREGATE}-Erweiterung für UDF-Funktionen.
@item Ross Wakelin @email{R.Wakelin@@march.co.uk}
Half, InstallShield für MySQL-Win32 aufzusetzen.
@item Jethro Wright III @email{jetman@@li.net}
Die @file{libmysql.dll}-Bibliothek.
@item James Pereria @email{jpereira@@iafrica.com}
Mysqlmanager, ein grafisches Win32-Werkzeug für die Administration von MySQL.
@item Curt Sampson @email{cjs@@portal.ca}
Portierung von MIT-pThread auf NetBSD/Alpha und NetBSD 1.3/i386.
@item Antony T. Curtis @email{antony.curtis@@olcs.net}
Portiierung von MySQL auf OS/2.
@item Martin Ramsch @email{m.ramsch@@computer.org}
Beispiele im MySQL-Tutorial.
@item Steve Harvey
Er machte @code{mysqlaccess} sicherer.
@item Konark IA-64 Centre of Persistent Systems Private Limited
@uref{http://www.pspl.co.in/konark/}. Hilfe bei der Win64-Portierung des
MySQL-Servers.
@item Albert Chin-A-Young.
Configure-Aktualisierungen für Tru64, Unterstützung großer Dateien und
verbesserte Unterstützung von TCP-Wrappern.
@item John Birrell
Emulation von pthread_mutex() für OS/2.
@item Benjamin Pflugmann
Erweiterte @code{MERGE}-Tabellen, so dass sie @code{INSERTS} handhaben.
Aktives Mitglied der MySQL-Mailing-Listen.
@end table

Andere Kontributoren, Bug-Finder und Tester: James H. Thompson, Maurizio
Menghini, Wojciech Tryc, Luca Berra, Zarko Mocnik, Wim Bonis, Elmar
Haneke, @email{jehamby@@lightside}, @email{psmith@@BayNetworks.com},
@email{duane@@connect.com.au}, Ted Deppner @email{ted@@psyber.com},
Mike Simons, Jaakko Hyvatti.

Und viele Bug-Berichte und Patches von den Leuten auf der Mailing-Liste.

Große Anerkennung zollen wir denjenigen, die uns halfen, Fragen auf der
@code{mysql@@lists.mysql.com}-Mailing-Liste zu beantworten:

@table @asis
@item Daniel Koch @email{dkoch@@amcity.com}
Irix-Setup.
@item Luuk de Boer @email{luuk@@wxs.nl}
Benchmark-Fragen.
@item Tim Sailer @email{tps@@Benutzer.buoy.com}
@code{DBD-mysql}-Fragen.
@item Boyd Lynn Gerber @email{gerberb@@zenez.com}
SCO-bezogene Fragen.
@item Richard Mehalick @email{RM186061@@shellus.com}
@code{xmysql}-bezogene Fragen und grundsätzliche Installationsfragen.
@item Zeev Suraski @email{bourbon@@netvision.net.il}
Fragen zur Apache-Modul-Konfiguration (log & auth), PHP-bezogene Fragen,
SQL-Syntax-bezogene Fragen und andere allgemeine Fragen.
@item France Guasch @email{frankie@@citel.upc.es}
Allgemeine Fragen.
@item Jonathan J Smith @email{jsmith@@wtp.net}
Fragen zu Betriebssystem-spezifschen Dingen bei Linux, SQL-Syntax- und
andere Dinge, die etwas Überarbeitung bedürfen.
@item David Sklar @email{sklar@@student.net}
MySQL von PHP und Perl aus benutzen.
@item Alistair MacDonald @email{A.MacDonald@@uel.ac.uk}
Noch nicht festgelegt, aber er ist flexibel und kann Linux und vielleicht
HP-UX handhaben. Wird versuchen, Benutzer dazu zu bringen, @code{mysqlbug}
zu benutzen.
@item John Lyon @email{jlyon@@imag.net}
Fragen zur Installation von MySQL auf Linux-Systemen, entweder mit
@file{.rpm}-Dateien oder durch Kompilieren vom Quelltext.
@item Lorvid Ltd. @email{lorvid@@WOLFENET.com}
Einfache Fragen zu Rechnung / Lizenz / Support / Copyright.
@item Patrick Sherrill @email{patrick@@coconet.com}
Fragen zur ODBC- und VisualC++-Schnittstelle.
@item Rundy Harmon @email{rjharmon@@uptimecomputers.com}
@code{DBD}, Linux, und einige SQL-Syntax-Fragen.
@end table


@node Supporters,  , Contributors, Credits
@c German node Unterstützer
@appendixsec Unterstützer von MySQL

@cindex Unterstützende Unternehmen, Auflistung

Während @code{MySQL AB} das gesammte Copyright für den @code{MySQL Server}
und das @code{MySQL manual} besitzt, möchten wir hier diejenigen Unternehmen
nennen, die die Entwicklung des @code{MySQL Servers} unterstützt haben.
Sie haben geholfen, indem sie uns für die Entwicklung eines neuen
Features bezahlten, indem sie MySQL-Features selbst entwickelten oder indem
sie uns Hardware für die MySQL-Entwicklung gaben.

@table @asis
@item VA Linux / Andover.net 
Stiftete Replikation.
@item NuSphere
Editieren des MySQL-Referenzhandbuchs.
@item Stork Design studio
Die MySQL-Website zwischen 1998 und 2000.
@item Intel
Trugen zur Entwicklung auf Windows- und Linux-Plattformen bei.
@item Compaq
Trugen zur Entwicklung auf Linux/Alpha bei.
@item SWSoft
Entwicklung der eingebetteten @code{mysqld}-Version.
@item FutureQuest
@code{--skip-show-variables}
@end table




@node News, Porting, Credits, Top
@c German node Neuigkeiten
@appendix MySQL-Änderungsverlauf (Change History)

@cindex ChangeLog
@cindex Änderungen, Log
@cindex Log, Änderungen

Dieser Anhang listet die Änderungen von Version zu Version im
MySQL-Quellcode auf.

Beachten Sie, dass wir versuchen, das Handbuch zeitgleich mit den
Änderungen an MySQL zu aktualisieren. Wenn Sie unten eine Version
aufgelistet sehen, die Sie auf der
@uref{http://www.mysql.com/downloads/,MySQL-Download-Seite} nicht finden
können, heißt das, dass die Version noch nicht veröffentlicht wurde!



@menu
* News-4.0.x::                  
* News-3.23.x::                 
@end menu

@node News-4.0.x, News-3.23.x, News, News
@c German node Neuigkeiten-4.0.x
@appendixsec Änderungen in Release 4.0.x (Entwicklung; Alpha)

Wir arbeiten mittlerweile aktiv an MySQL 4.0 und werden nur noch kritische
Bug-Bereinigungen für MySQL 3.23 herausgeben. Wir aktualisieren diesen
Abschnitt, wenn wir neue Features hinzufügen, so dass andere unserer
Entwicklung folgen können.

Unser TODO-Abschnitt enthält, was wir für 4.0 planen. @xref{TODO}.

@cindex Änderungen, Version 4.0


@menu
* News-4.0.2::                  
* News-4.0.1::                  
* News-4.0.0::                  
@end menu

@node News-4.0.2, News-4.0.1, News-4.0.x, News-4.0.x
@c German node Neuigkeiten-4.0.2
@appendixsubsec Änderungen in Release 4.0.2

@itemize @bullet
@item
Bug in @code{FLUSH QUERY CACHE} behoben.
@item
@code{CAST()}- und @code{CONVERT()}-Funktionen hinzugefügt.
@item
Reihenfolge geändert, wie Schlüssel in Tabellen erzeugt werden.
@item
Neue Spalten @code{Null} und @code{Index_type} zu @code{SHOW INDEX}
hinzugefügt.
@end itemize

@node News-4.0.1, News-4.0.0, News-4.0.2, News-4.0.x
@c German node Neuigkeiten-4.0.1
@appendixsubsec Änderungen in Release 4.0.1

@itemize @bullet
@item
Bug behoben, wenn @code{HANDLER} mit einem nicht unterstützten Tabellentyp
verwendet wurde.
@item
@code{mysqldump} schreibt jetzt @code{ALTER TABLE tabelle DISABLE KEYS} und
@code{ALTER TABLE tabelle DISABLE KEYS} in den SQL-Dump.
@item
@code{mysql_fix_extensions}-Skript hinzugefügt.
@item
Stack-Überlaufproblem @code{LOAD DATA FROM MASTER} auf OSF1 behoben.
@item
Herunterfahr-Problem auf HPUX behoben.
@item
Funktionen @code{des_encrypt()} und @code{des_decrypt()} hinzugefügt.
@item
Statement FLUSH DES_KEY_FILE hinzugefügt.
@item
mysqld-Option @code{--des-key-file} hinzugefügt.
@item
@code{HEX(string)} gibt jetzt die Buchstaben in der Zeichenkette
konvertiert in hexadezimal zurück.
@item
Problem mit @code{GRANT} bei der Benutzung von @code{lower_case_tables ==
1} behoben.
@item
@code{SELECT ... IN SHARE MODE} in @code{SELECT .. LOCK IN SHARE MODE} (wie
in MySQL 3.23) geändert.
@item
Ein neuer Anfragen-Cache, der Ergebnisse identischer @code{SELECT}-Anfragen
zwischenspeichert.
@item
Coredump-Bug auf 64-Bit-Maschinen beim Erhalt eines falschen
Kommunikationspakets behoben.
@item
@code{MATCH ... AGAINST(... IN BOOLEAN MODE)} funktioniert jetzt auch ohne
@code{FULLTEXT}-Index.
@item
Slave, der vom 3.23-Master repliziert, in Ordnung gebracht.
@item
Diverse Replikationsprobleme behoben / bereinigt.
@item
Herunterfahren funktioniert jetzt auf Mac OS X.
@item
@file{myisam/ft_dump}-Werkzeug zur Low-Level-Inspektion von
@code{FULLTEXT}-Indexen hinzugefügt.
@item
Bug in @code{DELETE ... WHERE ... MATCH ...} behoben.
@item
Unterstützung für @code{MATCH ... AGAINST(... IN BOOLEAN MODE)}
hinzugefügt. @strong{Hinweis: Sie müssen Ihre Tabellen mit
@code{ALTER TABLE tabelle TYPE=MyISAM} neu aufbauen, um Boole'sche
Volltextsuche benutzen zu können.}
@item
@code{LOCATE()} und @code{INSTR()} sind abhängig von der verwendeten
Groß-/Kleinschreibung, wenn keins der Argumente eine binäre Zeichenkette
ist.
@item
@code{RND()}-Initialisierung geändert, so dass @code{RND(N)} und
@code{RND(N+1)} verschiedener sind.
@item
Coredump-Bug in @code{UPDATE ... ORDER BY} behoben.
@item
@code{INSERT INTO .. SELECT} geändert, damit es bei Fehlern vorgabemäßig
anhält.
@item
@code{DATA DIRECTORY}- und @code{INDEX DIRECTORY}-Anweisungen werden unter
Windows ignoriert.
@item
Boole'sche Volltextsuche hinzugefügt. Diese sollte als frühe Alphaversion
betrachtet werden.
@item
@code{MODIFY} und @code{CHANGE} in @code{ALTER TABLE} erweitert, damit sie
das @code{AFTER}-Schlüsselwort akzeptieren.
@item
Index wird jetzt in @code{ORDER BY} von einer ganzen InnoDB-Tabelle
verwendet.
@end itemize

@node News-4.0.0,  , News-4.0.1, News-4.0.x
@c German node Neuigkeiten-4.0.0
@appendixsubsec Änderungen in Release 4.0.0

@itemize @bullet
@item
Variablen @code{ft_min_word_len}, @code{ft_max_word_len} und
@code{ft_max_word_len_for_sort} hinzugefügt.
@c German FIX removed extra @itemize @bullet from right here
@item
Dokumentation für @code{libmysqld}, die eingebettete
MySQL-Server-Bibliothek, hinzugefügt. Beispielprogramme (ein
@code{mysql}-Client und @code{mysqltest}-Testprogramm) hinzugefügt, die
@code{libmysqld} benutzen.
@item
@code{my_thread_init()} und @code{my_thread_end()} aus mysql_com.h entfernt
und @code{mysql_thread_init()} und @code{mysql_thread_end()} zu mysql.h
hinzugefügt.
@item
Vorzeichenlose @code{BIGINT}-Konstanten funktionieren jetzt. @code{MIN()}
und @code{MAX()} handhabt vorzeichenbehaftete und vorzeichenlose
@code{BIGINT}-Zahlen korrekt.
@item
Neuer Zeichensatz @code{latin_de}, der korrektes deutsches Sortieren
ermöglicht.
@item
@code{TRUNCATE TABLE} und @code{DELETE FROM tabelle} sind jetzt separate
Funktionen. Ein Vorteil davon ist, dass @code{DELETE FROM tabelle} jetzt
die Anzahl gelöschter Zeilen zurückgibt.
@item
@code{DROP DATABASE} führt jetzt ein @code{DROP TABLE} auf alle Tabellen in
der Datenbank aus, was ein Problem mit InnoDB-Tabellen behebt.
@item
Unterstützung für @code{UNION} hinzugefügt.
@item
Eine neue @code{HANDLER}-Schnittstelle zu @code{MyISAM}-Tabellen.
@item
Unterstützung für @code{INSERT} auf @code{MERGE}-Tabellen hinzugefügt.
Patch von Benjamin Pflugmann.
@item
@code{WEEK(#,0)} dem Kalender in den USA angepasst.
@item
@code{COUNT(DISTINCT)} ist etwa 30% schneller.
@item
Alle internen Listen-Handlings in der Geschwindigkeit verbessert.
@item
Das Erzeugen von Volltext-Indexen ist jetzt viel schneller.
@item
Baum-ähnlicher Cache, um Massen-Einfügevorgänge und die
@code{myisam_bulk_insert_tree_size}-Variable zu beschleunigen.
@item
Suchen auf komprimierten (@code{CHAR}/@code{VARCHAR})-Schlüsseln ist jetzt
viel schneller.
@item
Anfragen folgenden Typs optimiert:
@code{SELECT DISTINCT * from tabelle ORDER by schluessel_teil1 LIMIT #}
@item
@code{SHOW CREATE TABLE} zeigt jetzt alle Tabellenattribute.
@item
@code{ORDER BY ... DESC} kann jetzt Schlüssel benutzen.
@item
@code{LOAD DATA FROM MASTER} setzt jetzt "auto-magisch" einen Slave auf.
@item
@code{safe_mysqld} in @code{mysqld_safe} umbenannt.
@item
Unterstützung für symbolische Links auf @code{MyISAM}-Tabellen hinzugefügt.
Symlink-Handhabung ist jetzt vorgabemäßig für Windows aktiviert.
@item
@code{LOAD DATA FROM MASTER} setzt "auto-magisch" einen Slave auf.
@item
@code{SQL_CALC_FOUND_ROWS} und @code{FOUND_ROWS()} hinzugefügt. Das
ermöglicht es herauszufinden, wie viele Zeilen eine Anfrage ohne eine
@code{LIMIT}-Klausel zurückgegeben hätte.
@item
Ausgabeformat von @code{SHOW OPEN TABLES} geändert.
@item
@code{SELECT ausdruck LIMIT ...} wird zugelassen.
@item
@code{IDENTITY} als Synonym für @code{AUTO_INCREMENT} hinzugefügt (wie
Sybase).
@item
@code{ORDER BY}-Syntax zu @code{UPDATE} und @code{DELETE} hinzugefügt.
@item
@code{SHOW INDEXES} ist jetzt ein Synonym für @code{SHOW INDEX}.
@item
@code{ALTER TABLE tabelle DISABLE KEYS}- und @code{ALTER TABLE tabelle
ENABLE KEYS}-Befehle hinzugefügt.
@item
@code{IN} kann anstelle von @code{FROM} in @code{SHOW}-Befehlen benutzt
werden.
@item
ANSI-SQL-Syntax @code{X'Hexadezimalzahl'} wird zugelassen.
@item
Globale Sperr-Handhabung für @code{FLUSH TABLES with READ LOCK} aufgeräumt.
@item
Problem mit @code{DATETIME = constant} in @code{WHERE}-Optimierungen
behoben.
@end itemize


@node News-3.23.x,  , News-4.0.x, News
@c German node Neuigkeiten-3.23.x
@appendixsec Änderungen in Release 3.23.x  (Stabil)

@cindex changes, version 3.23

Das 3.23-Release hat etliche wichtige Features, die in früheren Versionen
nicht vorhanden sind. Es wurden drei neue Tabellentypen hinzugefügt:

@table @asis
@item @strong{MyISAM}
Eine neue ISAM-Bibliothek, die auf SQL und Unterstützung großer Dateien
abgestimmt ist. 
@item @strong{BerkeleyDB} oder @strong{BDB}
Benutzt die Berkeley-DB-Bibliothek von Sleepycat Software, um
transaktionssichere Tabellen zu implementieren.
@item @strong{InnoDB}
Ein transaktionssicherer Tabellen-Handler, der Sperren auf Zeilenebene und
viele Oracle-ähnliche Features unterstützt.
@end table

Beachten Sie, dass nur MyISAM in der Standard-Binärdistribution verfügbar
ist.

Das 3.23-Release beinhaltet ausserdem Unterstützung für
Datenbank-Replikation zwischen einem Master und vielen Slaves,
Volltext-Indexierung und vieles mehr.

Alle neuen Features werden in der 4.0-Version weiter entwickelt. Nur
Bug-Behebungen und kleinere Verbesserungen bestehender Features werden zu
3.23 hinzugefügt.

Der Replikationscode und der BerkeleyDB-Code sind noch nicht so gut
getestet wie der Rest des Codes, daher wird es wahrscheinlich zukünftig
noch einige Releases von 3.23 mit kleineren Behebungen für diesen Teil des
Codes geben. Solange Sie diese Features nicht benutzen, sollten Sie mit
MySQL 3.23 auf der sicheren Seite liegen!

Beachten Sie, dass das Gesagte nicht heißt, dass Replikation oder Berkeley
DB nicht funktionieren. Wir haben den gesamten Code ausgiebig getestet,
inklusive Replikation und BDB, ohne irgend welche Probleme zu finden. Es
heißt nur, dass nicht so viele Benutzer diesen Code verwenden wie den Rest
des Codes, weshalb wir noch nicht 100% auf diesen Teil des Codes vertrauen.


@menu
* News-3.23.43::                
* News-3.23.42::                
* News-3.23.41::                
* News-3.23.40::                
* News-3.23.39::                
* News-3.23.38::                
* News-3.23.37::                
* News-3.23.36::                
* News-3.23.35::                
* News-3.23.34a::               
* News-3.23.34::                
* News-3.23.33::                
* News-3.23.32::                
* News-3.23.31::                
* News-3.23.30::                
* News-3.23.29::                
* News-3.23.28::                
* News-3.23.27::                
* News-3.23.26::                
* News-3.23.25::                
* News-3.23.24::                
* News-3.23.23::                
* News-3.23.22::                
* News-3.23.21::                
* News-3.23.20::                
* News-3.23.19::                
* News-3.23.18::                
* News-3.23.17::                
* News-3.23.16::                
* News-3.23.15::                
* News-3.23.14::                
* News-3.23.13::                
* News-3.23.12::                
* News-3.23.11::                
* News-3.23.10::                
* News-3.23.9::                 
* News-3.23.8::                 
* News-3.23.7::                 
* News-3.23.6::                 
* News-3.23.5::                 
* News-3.23.4::                 
* News-3.23.3::                 
* News-3.23.2::                 
* News-3.23.1::                 
* News-3.23.0::                 
@end menu

@node News-3.23.43, News-3.23.42, News-3.23.x, News-3.23.x
@c German node Neuigkeiten-3.23.43
@appendixsubsec Änderungen in Release 3.23.43
@itemize @bullet
@item
Bug behoben, der mit sehr geringer Wahrscheinlichkeit auftritt, der keine
übereinstimmenden Zeilen zurückgab bei SELECT mit vielen Tabellen,
mehrspaltigen Indexen und 'Bereichs-'-Typen.
@item
Coredump-Bug behoben, der mit sehr geringer Wahrscheinlichkeit auftritt,
wenn man @code{EXPLAIN SELECT} mit vielen Tabellen und @code{ORDER BY}
ausführt.
@item
Bug in @code{LOAD DATA FROM MASTER} bei der Benutzung einer Tabelle mit
@code{CHECKSUM=1} behoben.
@item
Eindeutige Fehlermeldung hinzugefügt, die man bei einer Blockierung
(Deadlock) während einer Transaktion mit BDB-Tabellen erhält.
@item
Problem mit @code{BDB}-Tabellen und @code{UNIQUE}-Spalten, die als
@code{NULL} definiert wurden, behoben.
@item
Problem mit @code{myisampack} bei der Benutzung von CHAR-Spalten, die
Leerzeichen aufgefüllt wurden, behoben.
@item
Patch von Yuri Dario für OS2 angewandt.
@item
Bug in @code{--safe-user-create} behoben.
@end itemize

@node News-3.23.42, News-3.23.41, News-3.23.43, News-3.23.x
@c German node Neuigkeiten-3.23.42
@appendixsubsec Änderungen in Release 3.23.42
@itemize @bullet
@item
Problem bei der Benutzung von @code{LOCK TABLES} und @code{BDB}-Tabellen
behoben.
@item
Problem mit @code{REPAIR TABLE} auf MyISAM-Tabellen mit Zeilenlängen
zwischen 65517 und 65520 Bytes behoben.
@item
Seltenen Hänger bei @code{mysqladmin shutdown} behoben, wenn es viel
Aktivität auf einem anderen Thread gab.
@item
Problem mit @code{INSERT DELAYED} behoben, bei dem ein verzögerter Thread
auf @code{Upgrade locks} ohne ersichtlichen Grund hängen konnte.
@item
Problem mit @code{myisampack} und @code{BLOB} behoben.
@item
Problem beim Editieren von @code{.MRG}-Tabellen von Hand behoben.
(Patch von Benjamin Pflugmann).
@item
Es wird erzwungen, dass alle Tabellen in einer @code{MERGE}-Tabelle von
derselben Datenbank kommen.
@item
Bug mit @code{LOAD DATA INFILE} und transaktionalen Tabellen behoben.
@item
Bug bei der Benutzung von @code{INSERT DELAYED} mit falschen
Spaltendefinitionen behoben.
@item
Coredump während @code{REPAIR} besonders beschädigter Tabellen behoben.
@item
Bug in @code{InnoDB}- und @code{AUTO_INCREMENT}-Spalten behoben.
@item
Bug in @code{InnoDB} und @code{RENAME TABLE}-Spalten behoben.
@item
Kritischer Bug in @code{InnoDB}- und @code{BLOB}-Spalten behoben. Wenn man
@code{BLOB}-Spalten größer als 8000 Bytes in einer @code{InnoDB}-Tabelle
benutzte, musste man die Tabelle mit @code{mysqldump} sichern, löschen und
aus dem Dump neu aufbauen.
@item
Großen Patch für OS/2 von Yuri Dario angewandt.
@item
Problem mit @code{InnoDB} behoben, bei dem man den Fehler @code{Can't
execute the given command...} bekommen konnte, selbst wenn man keine aktive
Transaktion hatte.
@item
Einige kleine Probleme behoben, die Gemini betrafen.
@item
Echte arithmetische Operationen werden selbst dann in einem
Ganzzahl-Zusammenhang benutzt, wenn nicht alle Argumente Ganzzahlen sind.
(Behebt einen wenig häufigen Bug in einigen Ganzzahl-Kontexten.)
@item
Unter Windows wird nicht alles in Kleinschreibung erzwungen (um ein Problem
mit Windows und @code{ALTER TABLE} zu beheben). @code{--lower_case_names}
funktioniert jetzt auch unter Unix.
@item
Automatisches Rollback behoben, das ausgeführt wurde, wenn das Beenden
eines Threads keinen anderen Thread blockiert.
@end itemize

@node News-3.23.41, News-3.23.40, News-3.23.42, News-3.23.x
@c German node Neuigkeiten-3.23.41
@appendixsubsec Änderungen in Release 3.23.41

@itemize @bullet
@item
Option @code{--sql-mode=option[,option[,option]]} hinzugefügt.
@xref{Command-line options}.
@item
Mögliches Problem mit @code{shutdown} auf Solaris behoben, wobei die
@file{.pid}-Datei nicht gelöscht wurde.
@item
InnoDB unterstützt jetzt Zeilen < 4 GB. Die vorherige Beschränkung war
8.000 Bytes.
@item
Die @code{doublewrite}-Datei-Flush-Methode wird in InnoDB benutzt. Sie
reduziert die Notwendigkeit von Unix-fsync-Aufrufen auf einen Bruchteil und
verbessert die Performance auf den meisten Unix-Varianten.
@item
Sie können jetzt den InnoDB-Monitor benutzen, um etliche Informationen über
den InnoDB-Status auf die Standardausgabe auszugeben, inklusive Sperren.
Nützlich zum Tunen der Performance.
@item
Mehrere Bugs, die in InnoDB Hänger verursachen konnten, behoben.
@item
@code{record_buffer} in @code{record_buffer} und @code{record_rnd_buffer}
aufgeteilt. Um zu vorherigen MySQL-Versionen kompatibel zu bleiben, wird
@code{record_rnd_buffer} auf den Wert von @code{record_buffer} gesetzt,
wenn es nicht explizit gesetzt wird.
@item
Optimierungs-Bug in @code{ORDER BY} behoben, bei dem einige @code{ORDER
BY}-Teile fälschlicherweise entfernt wurden.
@item
Overflow-Bug bei @code{ALTER TABLE} und @code{MERGE}-Tabellen behoben.
@item
Prototypen für @code{my_thread_init()} und @code{my_thread_end()} zu
@file{mysql_com.h} hinzugefügt.
@item
Option @code{--safe-user-create} to @code{mysqld} hinzugefügt.
@item
Bug in @code{SELECT DISTINCT ... HAVING} behoben, der die Fehlermeldung
@code{Can't find record in '#...} verursachte.
@end itemize


@node News-3.23.40, News-3.23.39, News-3.23.41, News-3.23.x
@c German node Neuigkeiten-3.23.40
@appendixsubsec Änderungen in Release 3.23.40

@itemize @bullet
@item
Problem mit @code{--low-priority-updates} und @code{INSERT}'s behoben.
@item
Bug im Slave-Thread beseitigt, bei dem dieser in seltenen Fällen um 22 Byte
vor den Offset im Master kommen konnte.
@item
@code{slave_wait_timeout} für Replikation hinzugefügt.
@item
Problem mit @code{UPDATE} und @code{BDB}-Tabellen behoben.
@item
Problematischen Bug in @code{BDB}-Tabellen behoben, der bei der Benutzung
von Schlüsselteilen auftrat.
@item
Problem bei der Benutzung von @code{GRANT FILE ON datenbank.* ...} behoben.
Vorher wurde die @code{DROP}-Berechtigung für die Datenbank hinzugefügt.
@item
Bug bei @code{DELETE FROM tabelle ... LIMIT 0} und @code{UPDATE FROM
tabelle ... LIMIT 0} behoben, die sich vorher so verhielten, als gäbe es
keine @code{LIMIT}-Klausel (sie löschten oder aktualisierten alle
ausgewählten Zeilen).
@item
@code{CHECK TABLE} prüft jetzt, ob eine @code{AUTO_INCREMENT}-Spalte den
Wert 0 enthält.
@item
Wenn man @code{SIGHUP} an @code{mysqld} schickt, werden jetzt nur die Logs
auf Platte zurückgeschrieben (flush), nicht die Replikation zurückgesetzt.
@item
Parser in Ordnung gebracht, so dass er jetzt Fließkommazahlen des Typs
@code{1.0e1} (kein Vorzeichen nach @code{e}) zuläßt.
@item
Option @code{--force} für @code{myisamchk} aktualisiert jetzt auch Zustände
(Status).
@item
Option @code{--warnings} für @code{mysqld} hinzugefügt. @code{mysqld} gibt
jetzt nur den Fehler @code{Aborted connection} aus, wenn diese Option
benutzt wird.
@item
Problem mit @code{SHOW CREATE TABLE} behoben, wenn man keinen @code{PRIMARY
KEY} hatte.
@item
Saubere Behebung der Umbenennung von @code{innodb_unix_file_flush_method}
in @code{innodb_flush_method}.
@item
Bug beim Umwandeln von @code{UNSIGNED BIGINT} in @code{DOUBLE} behoben.
Dieser verursachte bei Vergleichen mit @code{BIGINT}-Werten ausserhalb des
vorzeichenbehafteten Bereichs ein Problem.
@item
Bug in @code{BDB}-Tabellen behoben, wenn man leere Tabellen abfragte.
@item
Bug bei der Benutzung von @code{COUNT(DISTINCT)} mit @code{LEFT JOIN}
behoben, wenn es keine übereinstimmenden Zeilen gab.
@item
Alle Dokumentation bezüglich @code{GEMINI}-Tabellen entfernt. @code{GEMINI}
wird nicht unter einer Open-Source-Lizenz herausgegeben.
@end itemize


@node News-3.23.39, News-3.23.38, News-3.23.40, News-3.23.x
@c German node Neuigkeiten-3.23.39
@appendixsubsec Änderungen in Release 3.23.39

@itemize @bullet
@item
Die @code{AUTO_INCREMENT}-Zahlenfolge wurde beim Löschen und Hinzufügen
einer @code{AUTO_INCREMENT}-Spalte nicht zurückgesetzt.
@item
@code{CREATE ... SELECT} erzeugt jetzt nicht eindeutige Indexe verzögert.
@item
Problem behoben, bei dem @code{LOCK TABLES tabelle READ} gefolgt von
@code{FLUSH TABLES} eine exklusive Sperre auf die Tabelle setzte.
@item
@code{REAL}-@@Variablen wurden mit 2 Ziffern dargestellt, wenn sie in
Zeichenketten umgewandelt wurden.
@item
Problem mit hängendem Client behoben, wenn @code{LOAD TABLE FROM MASTER}
fehlschlug.
@item
@code{myisamchk --fast --force} repariert jetzt keine Tabellen mehr, bei
denen nur der Öffnen-Zähler falsch ist.
@item
Funktionen zur Handhabung von symbolischen Links hinzugefügt, um sich das
Leben in Version 4.0 zu erleichtern.
@item
Wir benutzen jetzt die @code{-lcma}-Thread-Bibliothek unter HP-UX 10.20, so
dass MySQL auf HP-UX stabiler läuft.
@item
Problem mit @code{IF()} und Anzahl von Dezimalstellen im Ergebnis behoben.
@item
Funktionen zum Extrahieren von Datumsanteilen in Ordnung gebracht, so dass
sie jetzt mit Datumsangaben funktionieren, bei denen Tag und / oder Monat 0
sind.
@item
Argumentlänge in Optionsdateien von 256 auf 512 Zeichen erweitert.
@item
Problem bei Herunterfahren, wenn @code{INSERT DELAYED} auf ein @code{LOCK
TABLE} wartete, behoben.
@item
Coredump-Bug in InnoDB behoben, wenn der Tabellenplatz (Tablespace) voll
war.
@item
Problem mit @code{MERGE}-Tabellen und großen Tabellen (> 4 GB) und der
Benutzung von @code{ORDER BY} behoben.
@end itemize


@node News-3.23.38, News-3.23.37, News-3.23.39, News-3.23.x
@c German node Neuigkeiten-3.23.38
@appendixsubsec Änderungen in Release 3.23.38

@itemize @bullet
@item
Bug behoben, bei dem @code{SELECT} von @code{MERGE}-Tabellen manchmal zu
falsch sortierten Zeilen führte.
@item
Bug in @code{REPLACE()} bei der Benutzung des ujis-Zeichensatzes behoben.
@item
Sleepycat-BDB-Patches 3.2.9.1 und 3.2.9.2 angewandt.
@item
Option @code{--skip-stack-trace} zu @code{mysqld} hinzugefügt.
@item
@code{CREATE TEMPORARY} funktioniert jetzt mit @code{InnoDB}-Tabellen.
@item
@code{InnoDB} zieht jetzt Teile von Schlüsseln (Sub-Keys) ganzen Schlüsseln
vor.
@item
Option @code{CONCURRENT} für @code{LOAD DATA} hinzugefügt.
@item
Bessere Fehlermeldung, wenn die Slave-@code{max_allowed_packet}-Variable zu
niedrig ist, um ein sehr langes Log-Ereignis vom Master zu lesen.
@item
Bug behoben, wenn zu viele Zeilen bei der Benutzung von @code{SELECT
DISTINCT ... HAVING} entfernt wurden.
@item
@code{SHOW CREATE TABLE} gibt jetzt @code{TEMPORARY} für temporäre Tabellen
zurück.
@item
@code{Rows_examined} für Langsame-Anfragen-Log-Datei hinzugefügt.
@item
Probleme mit Funktion behoben, die eine leere Zeichenkette zurückgab, wenn
sie zusammen mit einer Gruppenfunktion und einem @code{WHERE} benutzt
wurde, das keine Zeilenübereinstimmung ergab.
@item
Neues Programm @code{mysqlcheck}.
@item
Datenbankname zur Ausgabe für administrative Befehle wie @code{CHECK},
@code{REPAIR}, @code{OPTIMIZE} hinzugefügt.
@item
Viele Portabilitätsbehebungen für InnoDB.
@item
Optimierer geändert, so dass Anfragen wie @code{SELECT * FROM
tabelle,tabelle2 ... ORDER BY schluessel_teil1 LIMIT #} den Index auf
@code{schluessel_teil1} anstelle von @code{filesort} benutzen.
@item
Bug bei der Ausführung von @code{LOCK TABLE to_table WRITE,...; INSERT INTO
to_table... SELECT ...} behoben, wenn @code{to_table} leer war.
@item
Bug mit @code{LOCK TABLE} und BDB-Tabellen behoben.
@end itemize


@node News-3.23.37, News-3.23.36, News-3.23.38, News-3.23.x
@c German node Neuigkeiten-3.23.37
@appendixsubsec Änderungen in Release 3.23.37

@itemize @bullet
@item
Bug bei der Benutzung von @code{MATCH} in @code{HAVING}-Klausel.
@item
Bug bei der Benutzung von @code{HEAP}-Tabellen mit @code{LIKE} behoben.
@item
@code{--mysql-version} für @code{safe_mysqld} hinzugefügt.
@item
@code{INNOBASE} in @code{InnoDB} geändert (weil der @code{INNOBASE}-Name
bereits benutzt wurde). Alle @code{configure}-Optionen und
@code{mysqld}-Startoptionen benutzen jetzt @code{innodb} anstelle von
@code{innobase}. Das heißt, dass Sie jegliche Konfigurationsdateien, in
denen Sie @code{innobase}-Optionen benutzt haben, ändern müssen, bevor Sie
auf diese Version aktualisieren!
@item
Bug bei der Benutzung von Indexen auf @code{CHAR(255) NULL}-Spalten
behoben.
@item
Slave-Thread wird jetzt auch dann gestartet, wenn @code{master-host} nicht
gesetzt ist, so lange @code{server-id} gesetzt wird und es eine gültige
@code{master.info} gibt.
@item
Teilweise Aktualisierungen (beendet mit kill) werden jetzt mit einem
speziellen Fehler-Code in die Binär-Log-Datei geschrieben. Der Slave
weigert sich, sie auszuführen, wenn der Fehler-Code anzeigt, dass die
Aktualisierung abnorm beendet wurde, und muss mit @code{SET
SQL_SLAVE_SKIP_COUNTER=1; SLAVE START} wieder dazu veranlasst werden,
nachdem eine manuelle Überprüfung / Korrektur der Datenintegrität
durchgeführt wurde.
@item
Bug behoben, der das Löschen einer internen temporären Tabelle beim Beenden
des Threads irrtümlicherweise in die Binär-Log-Datei schrieb. Dieser Bug
betraf Replikation.
@item
Bug in @code{REGEXP()} auf 64-Bit-Maschinen.
@item
@code{UPDATE} und @code{DELETE} mit @code{WHERE eindeutiger_schluessel_teil
IS NULL} aktualisierte / löschte nicht alle Zeilen.
@item
@code{INSERT DELAYED} für Tabellen abgeschaltet, die Transaktionen
unterstützen.
@item
Bug bei der Benutzung von DATE-Funktionen auf
@code{TEXT}/@code{BLOB}-Spalten mit falschem Datumsformat behoben.
@item
UDFs (benutzerdefinierte Funktionen) funktionieren jetzt auch unter
Windows (Patch von Ralph Masona).
@item
Bug in @code{ALTER TABLE} und @code{LOAD DATA INFILE} behoben, der das
Sortieren von Schlüsseln deaktivierte. Diese Befehle sollten jetzt in den
meisten Fällen schneller sein.
@item
Performance-Bug beim erneuten Öffnen von Tabellen behoben (Tabellen, die
auf ein @code{FLUSH} oder @code{REPAIR} warteten), die für die nächste
Anfrage keine Indexe benutzten.
@item
Problem mit @code{ALTER TABLE} für Innobase-Tabellen auf FreeBSD behoben.
@item
@code{mysqld}-Variablen @code{myisam_max_sort_file_size} und
@code{myisam_max_extra_sort_file_size} hinzugefügt.
@item
Signale werden frühzeitig initialisiert, um Problem mit Signalen in
Innobase zu vermeiden.
@item
Patch für den @code{tis620}-Zeichensatz hinzugefügt, um Vergleiche
unabhängig von der verwendeten Groß-/Kleinschreibung zu machen und einen
Bug in @code{LIKE} für diesen Zeichensatz zu beheben. @strong{HINWEIS}:
Alle Tabellen, die den @code{tis620}-Zeichensatz benutzen, müssen mit
@code{myisamchk -r} oder @code{REPAIR TABLE} in Ordnung gebracht werden!
@item
@code{--skip-safemalloc}-Option zu @code{mysqld} hinzugefügt.
@end itemize


@node News-3.23.36, News-3.23.35, News-3.23.37, News-3.23.x
@c German node Neuigkeiten-3.23.36
@appendixsubsec Änderungen in Release 3.23.36

@itemize @bullet
@item
Bug behoben, der Datenbanknamen mit einem @samp{.}-Zeichen zuließ. Das
behebt ein schwerwiegendes Sicherheitsproblem, wenn man @code{mysqld} unter
dem Benutzer root laufen läßt.
@item
Bug behoben, wenn die Erzeugung eines Threads fehlschlägt (das konnte bei
der Herstellung SEHR vieler Verbindungen in kurzer Zeit passieren).
@item
Einige Probleme mit @code{FLUSH TABLES} und @code{TEMPORARY}-Tabellen
behoben. (Problem mit dem Freisetzen des Schlüssel-Cache und Fehler
@code{Can't reopen table...}).
@item
Problem in Innobase mit anderen Zeichensätze als @code{latin1} und ein
anderes Problem bei der Benutzung von vielen Spalten behoben.
@item
Bug behoben, der einen Coredump bei der Benutzung einer sehr komplexen
Anfrage mit @code{DISTINCT} und Summenfunktionen verursachte.
@item
@code{SET TRANSACTION ISOLATION LEVEL ...} hinzugefügt.
@item
@code{SELECT ... FOR UPDATE} hinzugefügt.
@item
Bug behoben, bei dem die Anzahl von betroffenen Zeilen nicht zurückgegeben
wurde, wenn @code{MySQL} ohne Transaktionsunterstützung kompiliert wurde.
@item
Bug in @code{UPDATE} behoben, bei dem nicht immer Schlüssel benutzt wurden,
um die zu aktualisierenden Zeilen zu finden.
@item
Bug in @code{CONCAT_WS()} behoben, bei dem diese Funktion falsche
Ergebnisse zurückgab.
@item
@code{CREATE ... INSERT} und @code{INSERT ... SELECT} geändert, so dass
diese noch kleine gleichzeitigen Einfügevorgänge zulassen, weil das dazu
führen könnte, dass die Binär-Log-Datei schwer zu wiederholen ist.
(Gleichzeitige Einfügevorgänge sind aktiviert, wenn Sie nicht die Binär-
oder Update-Log-Datei verwenden.)
@item
Einige Makros geändert, so dass schnelles mutex mit glibc 2.2 verwendet
werden kann.
@end itemize


@node News-3.23.35, News-3.23.34a, News-3.23.36, News-3.23.x
@c German node Neuigkeiten-3.23.35
@appendixsubsec Änderungen in Release 3.23.35

@itemize @bullet
@item
Neu eingeführter Bug in @code{ORDER BY} behoben.
@item
Falsches Definieren von @code{CLIENT_TRANSACTIONS} behoben.
@item
Bug in @code{SHOW VARIABLES} bei der Benutzung von @code{INNOBASE}-Tabellen
behoben.
@item
Das Setzen und Benutzen von Benutzer-Variablen in @code{SELECT DISTINCT}
funktionierte nicht.
@item
@code{SHOW ANALYZE} für kleine Tabellen verbessert.
@item
Handhabung von Argumenten im Benchmark-Skript @file{run-all-tests} behoben.
@end itemize


@node News-3.23.34a, News-3.23.34, News-3.23.35, News-3.23.x
@c German node Neuigkeiten-3.23.34a
@appendixsubsec Änderungen in Release 3.23.34a

@itemize @bullet
@item
Zusätzliche Dateien zur Distribution hinzugefügt, die es ermöglichen, mit
@code{INNOBASE}-Unterstützung zu kompilieren.
@end itemize


@node News-3.23.34, News-3.23.33, News-3.23.34a, News-3.23.x
@c German node Neuigkeiten-3.23.34
@appendixsubsec Änderungen in Release 3.23.34

@itemize @bullet
@item
@code{INNOBASE}-Tabellen-Handler und @code{BDB}-Tabellen-Handler zur
MySQL-Quelldistribution hinzugefügt.
@item
Die Dokumentation zu @code{GEMINI}-Tabellen aktualisiert.
@item
Bug in @code{INSERT DELAYED} behoben, der den Thread zum Hängen brachte,
wenn @code{NULL} in eine @code{AUTO_INCREMENT}-Spalte eingefügt wurde.
@item
Bug in @code{CHECK TABLE} / @code{REPAIR TABLE} behoben, der einen Thread
zum Hängen bringen konnte.
@item
@code{REPLACE} ersetzt keine Zeile mehr, die mit einem durch
@code{auto_increment} erzeugten Schlüssel in Konflikt steht.
@item
@code{mysqld} setzt jetzt nur @code{CLIENT_TRANSACTIONS} in
@code{mysql->server_capabilities}, wenn der Server einen
transaktionssicheren Handler unterstützt.
@item
@code{LOAD DATA INFILE} läßt jetzt das Einfügen numerischer Werte in
@code{ENUM}- und @code{SET}-Spalten zu.
@item
Fehlerdiagnose beim Slave-Thread-Exit verbessert.
@item
Bug in @code{ALTER TABLE ... ORDER BY} behoben.
@item
Option @code{max_user_connections} für @code{mysqld} hinzugefügt.
@item
Anfragelänge für Replikation auf @code{max_allowed_packet} begrenzt, nicht
auf die willkürliche Länge von 4 MB.
@item
Leerzeichen um @code{=} herum im Argument zu @code{--set-variable} werden
zugelassen.
@item
Problem beim automatischen Reparieren behoben, der einen Thread im Zustand
@code{Waiting for table} lassen konnte.
@item
@code{SHOW CREATE TABLE} gibt jetzt das @code{UNION()} für
@code{MERGE}-Tabellen aus.
@item
@code{ALTER TABLE} merkt sich jetzt die alte @code{UNION()}-Definition.
@item
Bug beim Replizieren von Timestamps behoben.
@item
Bug bei der bidirektionalen Replikation behoben.
@item
Bug im @code{BDB}-Tabellen-Handler behoben, der bei der Benutzung eines
Indexes auf mehrteilige Schlüssel vorkam, wenn ein Schlüsselteil
@code{NULL} sein konnte.
@item
@code{MAX()}-Optimierung für Schlüsselteile (Sub-Keys) für
@code{BDB}-Tabellen verbessert.
@item
Problem behoben, bei dem 'Müll'-Ergebnisse bei der Benutzung von
@code{BDB}-Tabellen und @code{BLOB}- oder @code{TEXT}-Feldern beim
Verknüpfen (Join) vieler Tabellen auftraten.
@item
Problem mit @code{BDB}-Tabellen und @code{TEXT}-Spalten behoben.
@item
Bug bei der Benutzung eines @code{BLOB}-Schlüssels behoben, wenn eine
Konstanten-Zeile nicht gefunden wurde.
@item
Problem behoben, dass @code{mysqlbinlog} den Timestamp-Wert für jede
Anfrage schreibt. Das stellt sicher, dass man dieselben Werte bei
Datumsfunktionen wie @code{NOW()} bei der Benutzung von @code{mysqlbinlog}
erhält, um die Anfragen zu einem anderen Server durchzureichen (pipe).
@item
Es wird zugelassen, dass @code{--skip-gemini}, @code{--skip-bdb} und
@code{--skip-innobase} für @code{mysqld} angegeben werden, selbst wenn
diese Datenbanken nicht in @code{mysqld} einkompiliert sind.
@item
Man kann jetzt @code{GROUP BY ... DESC} ausführen.
@item
Blockierung im @code{SET}-Code behoben, wenn man @code{SET @@foo=bar}
ausführte, wobei @code{bar} ein Spaltenverweis ist. Hier wurde die
Fehlermeldung nicht korrekt erzeugt.
@end itemize


@node News-3.23.33, News-3.23.32, News-3.23.34, News-3.23.x
@c German node Neuigkeiten-3.23.33
@appendixsubsec Änderungen in Release 3.23.33

@itemize @bullet
@item
DNS-Lookups benutzen jetzt nicht mehr denselben mutex wie der
Hostnamen-Cache. Das gestattet, dass bekannte Hosts schnell aufgelöst
werden können, selbst wenn ein DNS-Lookup lange Zeit braucht.
@item
@code{--character-sets-dir} für @code{myisampack} hinzugefügt.
@item
Warnungen beim Laufenlassen von @code{REPAIR TABLE ... EXTENDED} entfernt.
@item
Bug, der einen Coredump bei der Benutzung von @code{GROUP BY} auf ein Alias
verursachte, wobei der Alias dasselbe wie ein existierender Spaltenname
war, entfernt.
@item
@code{SEQUENCE()} als Beispiel-UDF-Funktion hinzugefügt.
@item
@code{mysql_install_db} geändert, so dass es @code{BINARY} für
@code{CHAR}-Spalten in den Berechtigungstabellen benutzt.
@item
@code{TRUNCATE tabelle} zu @code{TRUNCATE TABLE tabelle} geändert, um
dieselbe Syntax wie Oracle zu verwenden. Bis Version 4.0 lassen wir
weiterhin @code{TRUNCATE tabelle} zu, um alten Code nicht zum Absturz zu
bringen.
@item
'no found rows'-Bug in @code{MyISAM}-Tabellen behoben, wenn ein @code{BLOB}
erster Teil eines mehrteiligen Schlüssels war.
@item
Bug behoben, bei dem @code{CASE} mit @code{GROUP BY} nicht funktionierte.
@item
Option @code{--sort-recover} für @code{myisamchk} hinzugefügt.
@item
@code{myisamchk -S} und @code{OPTIMIZE TABLE} funktionieren jetzt unter
Windows.
@item
Bug bei der Benutzung von @code{DISTINCT} auf Ergebnisse von Funktionen
behoben, die sich auf eine Gruppenfunktion bezogen, wie:
@example
SELECT a, DISTINCT SEC_TO_TIME(sum(a)) from tabelle GROUP BY a, b;
@end example
@item
Puffer-Überlauf in @code{libmysqlclient}-Bibliothek behoben. Bug bei der
Handhabung des @code{STOP}-Ereignisses nach @code{ROTATE}-Ereignis bei
Replikation.
@item
Einen weiteren Puffer-Überlauf in @code{DROP DATABASE} behoben.
@item
@code{Table_locks_immediate}- und
@code{Table_locks_waited}-Status-Variablen hinzugefügt.
@item
Bug in Replikation behoben, der den Slave-Server-Start bei existierendem
@code{master.info} unterbrach. Das behebt einen Bug, der in Version 3.23.32
eingeführt wurde.
@item
@code{SET SQL_SLAVE_SKIP_COUNTER=n}-Befehl hinzugefügt, um nach
Replikationsstörungen ohne volle Datenbankkopie wiederherzustellen.
@item
@code{max_binlog_size}-Variable hinzugefügt; die Binär-Log-Datei wird
automatisch rotiert, wenn die Größe die Grenze überschreitet.
@item
@code{Last_error}, @code{Last_errno} und @code{Slave_skip_counter} für
@code{SHOW SLAVE STATUS} hinzugefügt.
@item
Bug in @code{MASTER_POS_WAIT()}-Funktion behoben.
@item
Coredump-Handler auf @code{SIGILL} und @code{SIGBUS} zusätzlich zu
@code{SIGSEGV}.
@item
Auf x86-Linux wird im Coredump-Handler die aktuelle Anfrage und die Thread-
(Verbindungs-) Kennung, falls verfügbar, angegeben.
@item
Mehrere Timing-Bugs in der Test-Suite behoben.
@item
@code{mysqltest} erweitert, so dass es sich um Probleme mit dem Timing in
der Test-Suite kümmert.
@item
@code{ALTER TABLE} kann jetzt auch benutzt werden, um die Definition einer
@code{MERGE}-Tabelle zu ändern.
@item
Erzeugung von @code{MERGE}-Tabellen unter Windows in Ordnung gebracht.
@item
Portabilitätsbehebungen für OpenBSD und OS/2.
@item
@code{--temp-pool}-Option zu @code{mysqld} hinzugefügt. Das Benutzen dieser
Option führt dazu, dass temporäre Dateien nur einen kleinen Satz von Namen
benutzen, statt eines eindeutigen Namens für jede neue Datei. Das ist ein
Workaround um ein Problem im Linux-Kernel beim Erzeugen einer großen Menge
neuer Dateien mit unterschiedlichen Namen. Beim alten Verhalten scheint es
so, als ein Linux ein Speicher-'Loch' hätte, weil zum
Verzeichniseintrags-Cache statt zum Festplatten-Cache zugewiesen
(alloziert) wird.
@end itemize


@node News-3.23.32, News-3.23.31, News-3.23.33, News-3.23.x
@c German node Neuigkeiten-3.23.32
@appendixsubsec Änderungen in Release 3.23.32

@itemize @bullet
@item
Code geändert, um um einen Compiler-Bug in Compaq C++ auf OSF1
herumzuarbeiten, der @code{BACKUP}, @code{RESTORE}, @code{CHECK},
@code{REPAIR} und @code{ANALYZE TABLE} beschädigte.
@item
Option @code{FULL} für @code{SHOW COLUMNS} hinzugefügt. Jetzt wird die
Berechtigungsliste für die Spalten nur angezeigt, wenn diese Option
angegeben wird.
@item
Bug in @code{SHOW LOGS} behoben, wenn es keine BDB-Logs gab.
@item
Timing-Problem in Replikation behoben, dass das Abschicken einer
Aktualisierung an den Client verzögern konnte, bis eine weitere
Aktualisierung durchgeführt wurde.
@item
Feldnamen bei der Benutzung von @code{mysql_list_fields()} nicht umwandeln.
Damit bleibt dieser Code kompatibel mit @code{SHOW FIELDS}.
@item
@code{MERGE}-Tabellen funktionierten nicht unter Windows.
@item
Problem mit @code{SET PASSWORD=...} unter Windows.
@item
Fehlende @file{my_config.h} für RPM-Distribution hinzugefügt.
@item
@code{TRIM("foo" von "foo")} gab keine leere Zeichenkette zurück.
@item
@code{--with-version-suffix} für @code{configure} hinzugefügt.
@item
Coredump behoben, wenn der Client eine Verbindung ohne @code{mysql_close()}
abbrach.
@item
Bug in @code{RESTORE TABLE} behoben, wenn man versuchte, aus einem nicht
vorhandenen Verzeichnis wiederherzustellen.
@item
Bug behoben, der einen Coredump auf dem Slave bei der Replikation von
@code{SET PASSWORD} verursachte.
@item
@code{MASTER_POS_WAIT()} hinzugefügt.
@end itemize


@node News-3.23.31, News-3.23.30, News-3.23.32, News-3.23.x
@c German node Neuigkeiten-3.23.31
@appendixsubsec Änderungen in Release 3.23.31

@itemize @bullet
@item
Die Test-Suite testet jetzt jeden erreichbaren BDB-Schnittstellen-Code.
Während der Tests fanden und behoben wir viele Fehler im
Schnittstelle-Code.
@item
Die Benutzung von @code{HAVING} auf eine leere Tabelle konnte eine
Ergebniszeile ergeben, ohne dass es das sollte.
@item
Problem behoben, so dass das MySQL-RPM nicht mehr von Perl5 abhängt.
@item
Einige Probleme mit @code{HEAP}-Tabellen unter Windows behoben.
@item
@code{SHOW TABLE STATUS} zeigte nicht die korrekte durchschnittliche
Zeilenlänge bei Tabellen größer als 4 GB.
@item
@code{CHECK TABLE ... EXTENDED} prüften keine Zeilen-Links für Tabellen
fester Größe.
@item
Option @code{MEDIUM} für @code{CHECK TABLE} hinzugefügt.
@item
Problem bei der Benutzung von @code{DECIMAL()}-Schlüsseln auf negative
Zahlen behoben.
@item
@code{HOUR()} (und einige andere @code{TIME}-Funktionen) auf einer
@code{CHAR}-Spalte gaben immer @code{NULL} zurück.
@item
Sicherheits-Bug in etwas behoben (bitte aktualisieren Sie, wenn Sie eine
frühere MySQL-3.23-Version benutzen).
@item
Bug mit Puffer-Überlauf behoben, wenn eine bestimmte Fehlermeldung
ausgegeben wurde.
@item
Benutzung von @code{setrlimit()} unter Linux hinzugefügt, damit
@code{-O --open-files-limit=#} unter Linux läuft.
@item
Neue @code{mysqld}-Variable @code{bdb_version} hinzugefügt.
@item
Bug bei der Benutzung von Ausdrücken folgenden Typs behoben:
@example
SELECT ... FROM t1 LEFT JOIN t2 ON (t1.a=t2.a) WHERE t1.a=t2.a
@end example
In diesem Fall wurde der Test in der @code{WHERE}-Klausel fälschlicherweise
weg optimiert.
@item
Bug in @code{MyISAM} beim Löschen von Schlüsseln mit möglichen
@code{NULL}-Werten behoben, wenn die erste Schlüsselspalte keine
Präfix-komprimierte Text-Spalte war.
@item
@code{mysql.server} repariert, so dass es den
@code{mysql.server}-Optionsabschnitt anstelle von @code{mysql_server}
liest.
@item
@code{safe_mysqld} und @code{mysql.server} repariert, so dass sie den
@code{server}-Optionsabschnitt lesen.
@item
@code{thread_created}-Status-Variable zu @code{mysqld} hinzugefügt.
@end itemize


@node News-3.23.30, News-3.23.29, News-3.23.31, News-3.23.x
@c German node Neuigkeiten-3.23.30
@appendixsubsec Änderungen in Release 3.23.30

@itemize @bullet
@item
@code{SHOW OPEN TABLES}-Befehl hinzugefügt.
@item
@code{myisamdump} funktioniert jetzt mit alten @code{mysqld}-Servern.
@item
@code{myisamchk -k#} funktioniert jetzt wieder.
@item
Problem mit Replikation behoben, wenn die Binär-Log-Datei-Datei auf
32-Bit-Systemen größer als 2 GB wurde.
@item
@code{LOCK TABLES} startet jetzt automatisch eine neue Transaktion.
@item
@code{BDB}-Tabellen so geändert, dass sie interne Sub-Transaktionen
benutzen und offene Dateien wiederholt benutzen, um mehr Geschwindigkeit zu
erzielen.
@item
Option @code{--mysqld=#} für @code{safe_mysqld} hinzugefügt.
@item
Hexadezimale Konstanten in @code{--fields-*-by}- und
@code{--lines-terminated-by}-Optionen für @code{mysqldump} und
@code{mysqlimport} werden jetzt zugelassen. Von Paul DuBois.
@item
Option @code{--safe-show-Datenbank} für @code{mysqld} hinzugefügt.
@item
@code{have_bdb}, @code{have_gemini}, @code{have_innobase},
@code{have_raid} und @code{have_openssl} für @code{SHOW VARIABLES}
hinzugefügt, um das Testen auf unterstützte Erweiterungen zu erleichtern.
@item
Option @code{--open-files-limit} für @code{mysqld} hinzugefügt.
@item
Option @code{--open-files} zu @code{--open-files-limit} in
@code{safe_mysqld} geändert.
@item
Bug behoben, bei dem einige Zeilen nicht gefunden wurden, wenn
@code{HEAP}-Tabellen viele Schlüssel hatten.
@item
@code{--bdb-no-sync} funktioniert jetzt.
@item
@code{--bdb-recover} in @code{--bdb-no-recover} geändert, weil recover
vorgabemäßig angeschaltet sein sollte.
@item
Die vorgabemäßige Anzahl von BDB-Sperren auf 10.000 geändert.
@item
Bug aus Version 3.23.29 behoben, beim Zuweisen der gemeinsam genutzten
Struktur, die für BDB-Tabellen benötigt wird.
@item
@file{mysqld_multi.sh} für benutzerkonfigurierbare Variablen geändert.
Patch von Christopher McCrory.
@item
Include-Dateien für Solaris 2.8 in Ordnung gebracht.
@item
Bug mit @code{--skip-networking} auf Debian Linux behoben.
@item
Problem behoben, dass einige temporäre Dateien den Namen @code{UNOPENED} in
Fehlermeldungen hatten.
@item
Bug beim Laufenlassen von zwei gleichzeitigen @code{SHOW LOGS}-Anfragen
behoben.
@end itemize


@node News-3.23.29, News-3.23.28, News-3.23.30, News-3.23.x
@c German node Neuigkeiten-3.23.29
@appendixsubsec Änderungen in Release 3.23.29

@itemize @bullet
@item
Configure-Aktualisierungen für Tru64, Unterstützung großer Dateien und
besser TCP-Wrapper-Unterstützung. Von Albert Chin-A-Young.
@item
Bug in @code{<=>}-Operator behoben.
@item
Bug in @code{REPLACE} mit BDB-Tabellen behoben.
@item
@code{LPAD()} und @code{RPAD()} kürzen jetzt die Ergebnis-Zeichenkette,
wenn sie länger als das Längenargument ist.
@item
@code{SHOW LOGS}-Befehl hinzugefügt.
@item
Unbenutzte BDB-Logs werden beim Herunterfahren entfernt.
@item
Beim Erzeugen einer Tabelle werden @code{PRIMARY}-Schlüsseln zuerst
gesetzt, gefolgt von @code{UNIQUE}-Schlüsseln.
@item
Bug in @code{UPDATE} behoben, wenn mehrteilige Schlüssel benutzt wurden,
bei denen alle Schlüsselteile sowohl in der Aktualisierung als auch im
@code{WHERE}-Teil angegeben wurden. In diesem Fall könnte MySQL versuchen,
einen Datensatz zu aktualisieren, der nicht dem gesamten @code{WHERE}-Teil
entspricht.
@item
Löschen von Tabellen so geändert, dass zunächst die Tabelle und dann die
@file{.frm}-Datei gelöscht wird.
@item
Bug im Hostnamen-Cache behoben, der dazu führte, dass @code{mysqld} den
Hostnamen als @code{''} in manchen Fehlermeldungen berichtete.
@item
Bug mit @code{HEAP}-Tabellen behoben; die Variable
@code{max_heap_table_size} wurde nicht benutzt. Jetzt kann entweder
@code{MAX_ROWS} oder @code{max_heap_table_size} benutzt werden, um die
Größe einer @code{HEAP}-Tabelle zu beschränken.
@item
Die vorgabemäßige Server-Kennung auf 1 für Master-Server und 2 für Slaves
geändert, um die Benutzung der Binär-Log-Datei zu erleichtern.
@item
Variable @code{bdb_lock_max} in @code{bdb_max_lock} umbenannt.
@item
Unterstützung für @code{auto_increment} auf Unter-Felder (Sub-Fields) für
BDB-Tabellen hinzugefügt.
@item
@code{ANALYZE} von BDB-Tabellen hinzugefügt.
@item
In BDB-Tabellen wird jetzt die Anzahl von Zeilen gespeichert. Das hilft,
Anfragen zu optimieren, wenn dafür die ungefähre Anzahl von Zeilen benötigt
wird.
@item
Wenn es einen Fehler in einem mehrzeiligen Statement gibt, wird jetzt nur
das letzte Statement zurückgerollt, nicht die gesamte Transaktion.
@item
Wenn man @code{ROLLBACK} nach der Aktualisierung einer nicht
transaktionalen Tabelle ausführt, erhält man als Warnung einen Fehler.
@item
Option @code{--bdb-shared-data} für @code{mysqld} hinzugefügt.
@item
Status-Variable @code{Slave_open_temp_tables} hinzugefügt.
@item
Variablen @code{binlog_cache_size} und @code{max_binlog_cache_size} für
@code{mysqld} hinzugefügt.
@item
@code{DROP TABLE}, @code{RENAME TABLE}, @code{CREATE INDEX} und
@code{DROP INDEX} sind jetzt Transaktions-Endpunkte.
@item
Wenn Sie ein @code{DROP DATABASE} auf eine symbolisch verknüpfte Datenbank
ausführen, werden sowohl der Link als auch die Original-Datenbank gelöscht.
@item
@code{DROP DATABASE} funktioniert jetzt auf OS/2.
@item
Bug bei der Ausführung von @code{SELECT DISTINCT ... tabelle1 LEFT JOIN
tabelle2 ...} behoben, wenn tabelle2 leer war.
@item
@code{--abort-slave-event-count}- und
@code{--disconnect-slave-event-count}-Optionen für @code{mysqld} zum
Debuggen und Testen der Replikation hinzugefügt.
@item
Replikation temporärer Tabellen in Ordnung gebracht. Handhabt alles ausser
dem Neustart von Slaves.
@item
@code{SHOW KEYS} zeigt jetzt, ob ein Schlüssel @code{FULLTEXT} ist oder
nicht.
@item
Neues Skript @file{mysqld_multi}. @xref{mysqld_multi, , @code{mysqld_multi}}.
@item
Neues Skript @file{mysql-multi.server.sh} hinzugefügt. Vielen Dank an Tim
Bunce @email{Tim.Bunce@@ig.co.uk} für die Modifizierung von
@file{mysql.server}, um auf einfache Weise Hosts zu handhaben, die viele
@code{mysqld}-Prozesse laufen lassen.
@item
@file{safe_mysqld}, @file{mysql.server} und @file{mysql_install_db} wurden
so abgeändert, dass sie @code{mysql_print_defaults} anstelle verschiedener
Hacks benutzen, um @file{my.cnf}-Dateien zu lesen. Zusätzlich wurde die
Handhabung verschiedener Pfade konsistenter gemacht, in Bezug auf wie
@code{mysqld} vorgabemäßig handhabt.
@item
Berkeley-DB-Transaktions-Logs, die nicht mehr in Benutzung sind, werden
automatisch entfernt.
@item
Bug bei mehreren @code{FULLTEXT}-Indexen in einer Tabelle behoben.
@item
Warnung hinzugefügt, wenn sich die von Zeilen bei
@code{REPAIR}/@code{OPTIMIZE} ändert.
@item
Patches für OS/2 von @code{Yuri Dario} angewandt.
@item
@code{FLUSH TABLES tabelle} schrieb den Index-Baum nicht immer korrekt auf
die Festplatte zurück.
@item
@code{--bootstrap} läuft jetzt in einem separaten Thread. Das behebt ein
Problem, das bei @code{mysql_install_db} einen Coredump auf einigen
Linux-Maschinen verursachte.
@item
@code{mi_create()} abgeändert, so dass es weniger Stack-Platz benötigt.
@item
Bug beim Optimierer, wenn er versucht, @code{MATCH}, mit
@code{UNIQUE}-Schlüsseln benutzt, zu überoptimieren.
@item
@code{Crash-me} und die MySQL-Benchmarks funktionieren jetzt auch mit
FrontBase.
@item
@code{RESTRICT} und @code{CASCADE} werden nach einem @code{DROP TABLE}
zugelassen, um die Portierung einfacher zu machen.
@item
Status-Variable zurückgesetzt, die Probleme hervorrufen konnte, wenn man
@code{--slow-log} benutzte.
@item
Variable @code{connect_timeout} für @code{mysql} und @code{mysqladmin}
hinzugefügt.
@item
@code{connect_timeout} als Alias für @code{timeout} für Optionsdateien, die
von @code{mysql_options()} gelesen werden, hinzugefügt.
@end itemize


@node News-3.23.28, News-3.23.27, News-3.23.29, News-3.23.x
@c German node Neuigkeiten-3.23.28
@appendixsubsec Änderungen in Release 3.23.28

@itemize @bullet
@item
Neue Optionen @code{--pager[=...]}, @code{--no-pager}, @code{--tee=...} und
@code{--no-tee} für den @code{mysql}-Client hinzugefügt. Die entsprechenden
neuen interaktiven Befehle heißen @code{pager}, @code{nopager}, @code{tee}
und @code{notee}. Siehe @xref{mysql, , @code{mysql}}, @code{mysql --help}
und die interaktive Hilfe wegen weiterer Informationen.
@item
Absturz behoben, der beim Fehlschlagen der Reparatur von
@code{MyISAM}-Tabellen auftrat.
@item
Größerer Performance-Bug im Tabellensperren-Code behoben, wenn man
permanent VIELE @code{SELECT}-, @code{UPDATE}- und @code{INSERT}-Statements
laufen hatte. Das Symptom zeigte sich darin, dass die @code{UPDATE}- und
@code{INSERT}-Anfragen lange gesperrt waren, während neue
@code{SELECT}-Statements vor den Aktualisierungen ausgeführt wurden.
@item
Beim Lesen von @code{options_files} mit @code{mysql_options()} wurde die
@code{return-found-rows}-Option ignoriert.
@item
Man kann jetzt @code{interactive-timeout} in der Optionsdatei angeben, die
von @code{mysql_options()} gelesen wird. Das ermöglicht es, Programme, die
lange laufen (wie @code{mysqlhotcopy}), zu zwingen,
@code{interactive_timeout} anstelle von @code{wait_timeout} zu benutzen.
@item
Zur Langsame-Anfragen-Log-Datei Zeit und Benutzernamen für jede geloggte
Anfrage hinzugefügt. Wenn Sie @code{--log-long-format} benutzen, werden
auch Anfragen, die keinen Index benutzen, geloggt, selbst wenn die Anfrage
weniger als @code{long_query_time} Sekunden benötigt.
@item
Problem in @code{LEFT JOIN} behoben, was dazu führte, dass alle Spalten in
einer Verweistabelle @code{NULL} waren.
@item
Problem bei der Benutzung von @code{NATURAL JOIN} ohne Schlüssel behoben.
@item
Bug bei der Benutzung eines mehrteiligen Schlüssels behoben, bei dem der
erste Teil vom Typ @code{TEXT} oder @code{BLOB} war.
@item
@code{DROP} von temporären Tabellen wurde nicht in der
Update-/Binär-Log-Datei gespeichert.
@item
Bug behoben, der bei @code{SELECT DISTINCT * ... LIMIT #} nur eine Zeile
zurückgab.
@item
Bug im Assembler-Code in @code{strstr()} für sparc behoben und
@file{global.h}-Header-Datei aufgeräumt, um ein Problem mit schlechtem
Aliasing des Compilers zu vermeiden, der bei RedHat 7.0 beiliegt (berichtet
von Trond Eivind Glomsrød).
@item
Die Option @code{--skip-networking} funktioniert jetzt sauber unter Windows
NT.
@item
Lang ausstehender Bug in den @code{ISAM}-Tabellen behoben, wenn eine Zeile
mit einer Länge von mehr als 65 KB um ein einzelnes Byte gekürzt wurde.
@item
Bug in @code{MyISAM} beim Laufenlassen mehrfacher Aktualisierungsprozesse
auf dieselbe Tabelle behoben.
@item
Es wird zugelassen, dass @code{FLUSH TABLE tabelle} benutzt wird.
@item
@code{--replicate-ignore-table}, @code{--replicate-do-table},
@code{--replicate-wild-ignore-table} und @code{--replicate-wild-do-table}
hinzugefügt.
@item
Alle Log-Dateien so geändert, dass sie unseren eigenen
@code{IO_CACHE}-Mechanismus anstelle von @code{FILE} benutzen, um
Betriebssystemprobleme zu vermeiden, wenn zu viele Dateien offen sind.
@item
Optionen @code{--open-files} und @code{--timezone} für @code{safe_mysqld}
hinzugefügt.
@item
Schweren Bug in @code{CREATE TEMPORARY TABLE ... SELECT ...} behoben.
@item
Problem mit @code{CREATE TABLE ... SELECT NULL} behoben.
@item
Variablen @code{large_file_support}, @code{net_read_timeout},
@code{net_write_timeout} und @code{query_buffer_size} für @code{SHOW
VARIABLES} hinzugefügt.
@item
Status-Variablen @code{created_tmp_files} und @code{sort_merge_passes} für
@code{SHOW STATUS} hinzugefügt.
@item
Bug behoben, bei dem kein Index-Name nach der @code{FOREIGN KEY}-Definition
zugelassen wurde.
@item
@code{TRUNCATE tabelle} als ein Synonym für @code{DELETE FROM tabelle}
hinzugefügt.
@item
Bug in einer BDB-Schlüsselvergleichsfunktion beim Vergleich von
Schlüsselteilen behoben.
@item
Variable @code{bdb_lock_max} für @code{mysqld} hinzugefügt.
@item
Weitere Tests zur Benchmark-Suite hinzugefügt.
@item
Überlauf-Bug im Client-Code bei der Benutzung von überlangen Datenbanknamen
behoben.
@item
@code{mysql_connect()} bricht jetzt unter Linux ab, wenn der Server nicht
in @code{timeout} Sekunden antwortet.
@item
@code{SLAVE START} funktionierte nicht, wenn Sie mit
@code{--skip-slave-start} starteten und vorher nicht explizit @code{CHANGE
MASTER TO} laufen ließen.
@item
Die Ausgabe von @code{SHOW MASTER STATUS} in Ordnung gebracht, damit sie
konsistent mit @code{SHOW SLAVE STATUS} ist. (Sie hat jetzt kein
Verzeichnis im Log-Namen.)
@item
@code{PURGE MASTER LOGS TO} hinzugefügt.
@item
@code{SHOW MASTER LOGS} hinzugefügt.
@item
@code{--safemalloc-mem-limit}-Option für @code{mysqld} hinzugefügt, um
Speichermangel zu simulieren, wenn mit @code{--with-debug=full} kompiliert
wurde.
@item
Mehrere Coredumps unter Bedingungen, in denen Arbeitsspeicher fehlt,
behoben.
@item
@code{SHOW SLAVE STATUS} benutzte einen nicht initialisierten mutex, wenn
der Slave noch nicht gestartet wurde.
@item
Bug in @code{ELT()} und @code{MAKE_SET()} behoben, wenn die Anfrage eine
temporäre Tabelle benutzte.
@item
@code{CHANGE MASTER TO} ohne Angabe von @code{MASTER_LOG_POS} setzte es auf
0 statt auf 4 und erreichte die magische Zahl im binären Master-Log.
@item
@code{ALTER TABLE ... ORDER BY ...}-Syntax hinzugefügt. Das erzeugt die
Tabelle mit Zeilen in einer festgelegten Reihenfolge.
@end itemize


@node News-3.23.27, News-3.23.26, News-3.23.28, News-3.23.x
@c German node Neuigkeiten-3.23.27
@appendixsubsec Änderungen in Release 3.23.27

@itemize @bullet
@item
Bug behoben, bei dem das automatische Reparieren von MyISAM-Tabellen
manchmal fehlschlug, wenn die Daten-Datei beschädigt war.
@item
Bug in @code{SHOW CREATE} bei der Benutzung von
@code{AUTO_INCREMENT}-Spalten behoben.
@item
BDB-Tabellen so geändert, dass sie die neue Vergleichsfunktion in Berkeley
DB 3.2.3 benutzen.
@item
Sie können jetzt Unix-Sockets bei @code{mit-pThread} benutzen.
@item
Neuer latin5- (türkischer) Zeichensatz.
@item
Kleinere Portabilitätsbehebungen.
@end itemize


@node News-3.23.26, News-3.23.25, News-3.23.27, News-3.23.x
@c German node Neuigkeiten-3.23.26
@appendixsubsec Änderungen in Release 3.23.26

@itemize @bullet
@item
@code{<>} funktioniert jetzt sauber mit @code{NULL}.
@item
Problem mit @code{SUBSTRING_INDEX()} und @code{REPLACE()} behoben (Patch
von Alexunder Igonitchev).
@item
@code{CREATE TEMPORARY TABLE IF NOT EXISTS} gab keinen Fehler, wenn die
Tabelle existierte.
@item
Wenn Sie keinen @code{PRIMARY KEY} in einer BDB-Tabelle erzeugen, wird ein
versteckter @code{PRIMARY KEY} erzeugt.
@item
Nur-Lese-Schlüssel-Optimierung to BDB-Tabellen hinzugefügt.
@item
@code{LEFT JOIN} bevorzugte in manchen Fällen einen vollen Tabellen-Scan,
wenn es keine @code{WHERE}-Klausel gab.
@item
Bei der Benutzung von @code{--log-slow-query} die Wartezeit auf eine Sperre
nicht zählen.
@item
Bug im Sperr-Code unter Windows behoben, der dazu führte, dass der
Schlüssel-Cache berichtete, dass die Schlüssel-Datei beschädigt sei, obwohl
sie in Ordnung war.
@item
Automatische Reparatur von @code{MyISAM}-Tabellen, wenn Sie @code{mysqld}
mit @code{--myisam-recover} starten, hinzugefügt.
@item
Das @code{TYPE=}-Schlüsselwort wurde von @code{CHECK} und @code{REPAIR}
entfernt. Es wird zugelassen, dass @code{CHECK}-Optionen kombiniert werden.
(Sie können immer noch @code{TYPE=} benutzen, aber die Benutzung wird nicht
empfohlen.)
@item
Mutex-Bug im binären Replikations-Log behoben - lange
Aktualisierungsanfragen konnten vom Slave nur teilweise gelesen werden,
wenn er das zur falschen Zeit machte, was nicht schwerwiegend ist, aber zu
einem Performance-verschlechternden erneuten Verbinden führte, sowie zu
einer beunruhigenden Nachricht in der Fehler-Log-Datei.
@item
Das Format der Binär-Log-Datei wurde geändert - hinzugefügt wurden magische
Zahl, Serverversion, Binlog-Version, Server-Kennung und Anfragen-Fehlercode
für jedes Anfrage-Ereignis.
@item
Replikations-Thread vom Slave killt jetzt alle darnieder liegenden Threads
vom selben Server.
@item
Lange Replikations-Benutzernamen wurden bislang nicht korrekt gehandhabt.
@item
@code{--replicate-rewrite-db}-Option zu @code{mysqld} hinzugefügt.
@item
@code{--skip-slave-start}-Option to @code{mysqld} hinzugefügt.
@item
Aktualisierungen, die einen Fehlercode erzeugten (wie @code{INSERT INTO
foo(schluessel) values (1),(1)}) beendeten bislang irrtümlich den
Slave-Thread.
@item
Optimierung von Anfragen, bei denen @code{DISTINCT} nur auf Spalten aus
denselben Tabellen benutzt wird, hinzugefügt.
@item
Fließkommazahlen ohne Vorzeichen nach dem Exponent (wie 1e1) werden
zugelassen.
@item
@code{SHOW GRANTS} zeigte nicht immer alle Spaltenberechtigungen.
@item
@code{--default-extra-file=#} für alle MySQL-Clients hinzugefügt.
@item
Spalten, auf die in @code{INSERT}-Statements verwiesen wird, werden nun
sauber initialisiert.
@item
@code{UPDATE} funktioniert nicht immer, wenn es mit einem Bereich auf einem
Timestamp benutzt wurde, der Teil des Schlüssels war, der benutzt wurde, um
Zeilen zu finden.
@item
Bug in @code{FULLTEXT}-Index beim Einfügen einer @code{NULL}-Spalte
behoben.
@item
@code{mkstemp()} wird jetzt anstelle von @code{tempnam()} benutzt. Basiert
auf einem Patch von John Jones.
@end itemize


@node News-3.23.25, News-3.23.24, News-3.23.26, News-3.23.x
@c German node Neuigkeiten-3.23.25
@appendixsubsec Änderungen in Release 3.23.25

@itemize @bullet
@item
@code{database} funktioniert als zweites Argument für @code{mysqlhotcopy}.
@item
@code{UMASK} und @code{UMASK_DIR} können jetzt oktal angegeben werden.
@item
@code{RIGHT JOIN}. Hierdurch wird @code{RIGHT} zu einem reservierten Wort.
@item
@code{@@@@IDENTITY} als ein Synonym für @code{LAST_INSERT_ID()}
hinzugefügt, aus Gründen der Visual-Basic-Kompatibilität.)
@item
Bug in @code{myisamchk} und @code{REPAIR} bei der Benutzung von
@code{FULLTEXT}-Indexen behoben.
@item
@code{LOAD DATA INFILE} funktioniert jetzt mit FIFOs (Patch von Toni L.
Harbaugh-Blackford).
@item
@code{FLUSH LOGS} brach die Replikation ab, wenn Sie einen Log-Namen mit
einer expliziten Erweiterung als Wert der @code{log-bin}-Option angaben.
@item
Bug in @code{MyISAM} mit komprimierten mehrteiligen Schlüsseln behoben.
@item
Absturz bei der Benutzung von @code{CHECK TABLE} unter Windows behoben.
@item
Bug, bei dem @code{FULLTEXT}-Index immer den koi8_ukr-Zeichensatz
benutzten, behoben.
@item
Berechtigungsüberprüfung für @code{CHECK TABLE} in Ordnung gebracht.
@item
Der @code{MyISAM}-Reparatur-/Reindexierungs-Code benutzte nicht die
@code{--tempdir}-Option für seine temporären Dateien.
@item
@code{BACKUP TABLE/RESTORE TABLE} hinzugefügt.
@item
Coredump auf @code{CHANGE MASTER TO} behoben, wenn der Slave keinen Master
hatte, mit dem er startet.
@item
Falsche @code{time} in der Prozessliste für @code{Connect} des
Slave-Threads in Ordnung gebracht.
@item
Der Slave loggt jetzt, wann er sich mit dem Master verbindet.
@item
Coredump-Bug beim Ausführen von @code{FLUSH MASTER} behoben, wenn man kein
Dateinamens-Argument für @code{--log-bin} angab.
@item
Fehlende @file{ha_berkeley.x}-Dateien zu MySQL unter Windows hinzugefügt.
@item
Einige mutex-Bugs im Log-Code behoben, die zu Thread-Blockierungen führen
konnten, wenn neue Log-Dateien nicht erzeugt werden konnten.
@item
Sperrzeit und Anzahl von ausgewählten bearbeiteten Zeilen zur
Langsame-Anfragen-Log-Datei hinzugefügt.
@item
@code{--memlock}-Option für @code{mysqld}, um @code{mysqld} im
Arbeitsspeicher auf Systemen mit dem @code{mlockall()}-Aufruf (wie in
Solaris) zu sperren, hinzugefügt.
@item
@code{HEAP}-Tabellen benutzten Schlüssel nicht korrekt (Bug aus Version
3.23.23).
@item
Bessere Unterstützung für @code{MERGE}-Tabellen (Schlüssel, Mapping,
Erzeugung, Dokumentation und mehr) hinzugefügt. @xref{MERGE}.
@item
Bug in @code{mysqldump} aus Version 3.23 behoben, der dazu führte, dass
einige @code{CHAR}-Spalten nicht in Anführungsstrichen standen.
@item
@code{analyze}, @code{check}, @code{optimize} und Reparatur-Code
zusammengefasst.
@item
@code{OPTIMIZE TABLE} wird jetzt auf @code{REPAIR} mit Statistiken und
Sortieren des Index-Baums gemappt. Das heißt, das es momentan nur auf
@code{MyISAM}-Tabellen funktioniert.
@item
Einen pre-alloced Block zu root_malloc hinzugefügt, um weniger mallocs zu
erhalten.
@item
Viele neue Statistik-Variablen hinzugefügt.
@item
@code{ORDER BY}-Bug bei BDB-Tabellen behoben.
@item
Warnungen entfernt, dass @code{mysqld} die @file{.pid}-Datei unter Windows
nicht entfernen konnte.
@item
@code{--log-isam} zum Loggen von @strong{MyISAM}-Tabellen anstelle von
isam-Tabellen abgeändert.
@item
@code{CHECK TABLE} funktioniert jetzt auch unter Windows.
@item
Datei-mutexes hinzugefügt, um @code{pwrite()} unter Windows sicher zu
machen.
@end itemize


@node News-3.23.24, News-3.23.23, News-3.23.25, News-3.23.x
@c German node Neuigkeiten-3.23.24
@appendixsubsec Änderungen in Release 3.23.24

@itemize @bullet
@item
@code{mysqld}-Variable @code{created_tmp_disk_tables} hinzugefügt.
@item
Um das verlässliche Dumpen und Wiederherstellen von Tabellen mit
@code{TIMESTAMP(X)}-Spalten zu ermöglichen, berichtet MySQL jetzt Spalten
mit @code{X} anders als 14 oder 8 als Zeichenketten.
@item
Sortierreihenfolge für latin1 abgeändert im Vergleich zu MySQL-Version vor
3.23.23. Jede Tabelle mit @code{CHAR}-Spalten, die Zeichen mit ASCII-Werten
größer als 128 enthalten darf, die vor Version 3.23.22 erzeugt oder
geändert wurde, muss repariert werden!
@item
Kleines Speicherleck behoben, das in Version 3.23.22 beim Einfügen einer
temporären Tabelle eingeführt wurde.
@item
Problem mit BDB-Tabellen und Lesen auf einem eindeutigen (nicht primären)
Schlüssel behoben.
@item
Der win1251-Zeichensatz wurde wiederhergestellt (er ist jetzt nur als nicht
empfohlen gekennzeichnet).
@end itemize


@node News-3.23.23, News-3.23.22, News-3.23.24, News-3.23.x
@c German node Neuigkeiten-3.23.23
@appendixsubsec Änderungen in Release 3.23.23

@itemize @bullet
@item
Geänderte Sortierreihenfolge für 'deutsch'; Alle Tabellen mit 'deutscher'
Sortierreihenfolge müssen mit @code{REPAIR TABLE} oder @code{myisamchk}
repariert werden, bevor sie benutzt werden können!
@item
Option @code{--core-file} für @code{mysqld} hinzugefügt, um eine Core-Datei
unter Linux zu erhalten, wenn @code{mysqld} durch das SIGSEGV-Signal
stirbt.
@item
MySQL-Client @code{mysql} startet jetzt vorgabemäßig mit
@code{--no-named-commands} (@code{-g}). Diese Option kann mit
@code{--enable-named-commands} (@code{-G}) abgeschaltet werden. Das kann in
manchen Fällen Inkompatibilitätsprobleme hervorrufen, zum Beispiel in
SQL-Skripten, die benannte Befehle ohne Semikolon benutzen!
Langformat-Befehle funktionieren immer noch von der ersten Zeile.
@item
Problem bei der Benutzung vieler anhängiger @code{DROP TABLE}-Statements
zugleich behoben.
@item
Der Optimierer verwendete Schlüssel nicht korrekt bei der Benutzung von
@code{LEFT JOIN} auf eine leere Tabelle.
@item
Kürzerer Hilfetext beim Aufruf von @code{mysqld} mit falschen Optionen.
@item
Nicht schwerwiegender @code{free()}-Bug in @code{mysqlimport} behoben.
@item
Bug in der @code{MyISAM}-Index-Handhabung von
@code{DECIMAL}-/@code{NUMERIC}-Schlüsseln behoben.
@item
Bug beim gleichzeitigen Einfügen in @code{MyISAM}-Tabellen behoben; in
manchen Zusammenhängen gab die Benutzung von @code{MIN(schluessel_teil)}
oder @code{MAX(schluessel_teil)} eine leere Ergebnismenge zurück.
@item
@code{mysqlhotcopy} für die Benutzung der neuen @code{FLUSH TABLES
tabellen_liste}-Syntax aktualisiert. Nur Tabellen, die gesichert werden,
werden jetzt auf Platte zurückgeschrieben (flush).
@item
Verhalten von @code{--enable-thread-safe-client} so geändert, dass sowohl
nicht gethreadete (@code{-lmysqlclient}) als auch gethreadete
(@code{-lmysqlclient_r}) Bibliotheken eingebaut werden. Benutzer, die gegen
ein gethreadetes @code{-lmysqlclient} linkten, müssen jetzt gegen
@code{libmysqlclient_r} linken.
@item
Atomischer @code{RENAME}-Befehl hinzugefügt.
@item
Einträge mit @code{NULL} werden in @code{COUNT(DISTINCT ...)} nicht
gezählt.
@item
@code{ALTER TABLE}, @code{LOAD DATA INFILE} auf leere Tabellen und
@code{INSERT ... SELECT ...} auf leere Tabellen so geändert, dass nicht
eindeutige Indexe in einem separaten Stapellauf mit Sortieren erzeugt
werden. Das macht die genannten Aufrufe viel schneller, wenn Sie viele
Indexe haben.
@item
@code{ALTER TABLE} loggt jetzt die zuerst benutzte insert_id korrekt.
@item
Absturz beim Hinzufügen eines Vorgabewerts zu einer @code{BLOB}-Spalte
behoben.
@item
Bug bei @code{DATE_ADD/DATE_SUB} behoben, der eine DATETIME anstelle eines
DATE zurückgab.
@item
Problem mit dem Thread-Cache behoben, der dazu führte, dass einige Threads
als @code{***DEAD***} in @code{SHOW PROCESSLIST} erschienen.
@item
Eine Sperre in unserem thr_rwlock-Code beseitigt, die dazu führen konnte,
dass SELECTs, die zur selben Zeit laufen wie gleichzeitige Einfügevorgänge,
abstürzen. Das betrifft nur Systeme, die nicht den
@code{pthread_rwlock_rdlock}-Code haben.
@item
Beim Löschen von Zeilen mit einem nicht eindeutigen Schlüssel in einer
HEAP-Tabelle wurden nicht immer alle Zeilen gelöscht.
@item
Bug im Bereichsoptimierer für HEAP-Tabellen bei Suchen auf einem Teil-Index
behoben.
@item
@code{SELECT} auf Teilschlüsseln funktioniert jetzt bei BDB-Tabellen.
@item
@code{INSERT INTO bdb_tabelle ... SELECT} funktioniert jetzt bei
BDB-Tabellen.
@item
@code{CHECK TABLE} aktualisiert jetzt Schlüsselstatistiken für die Tabelle.
@item
@code{ANALYZE TABLE} aktualisiert jetzt nur Tabellen, die seit dem letzten
@code{ANALYZE} geändert wurden. Beachten Sie, dass das ein neues Feature
ist, und dass Tabellen nicht als analysiert gekennzeichnet werden, bis sie
auf irgend eine Weise mit Version 3.23.23 oder neuer aktualisiert wurden.
Bei älteren Tabellen müssen Sie @code{CHECK TABLE} ausführen, um die
Schlüsselverteilung zu aktualisieren.
@item
Einige kleinere Berechtigungsprobleme bei @code{CHECK}, @code{ANALYZE},
@code{REPAIR} und @code{SHOW CREATE} behoben.
@item
@code{CHANGE MASTER TO}-Befehl hinzugefügt.
@item
@code{FAST}-, @code{QUICK}- @code{EXTENDED}-Überprüfungsarten zu
@code{CHECK TABLES} hinzugefügt.
@item
@code{myisamchk} abgeändert, so dass @code{--fast} und
@code{--check-changed-tables} auch bei @code{--sort-index} und
@code{--analyze} berücksichtigt werden.
@item
Schwerwiegenden Bug in @code{LOAD TABLE FROM MASTER} behoben, bei dem die
Tabelle während des Neuaufbaus des Indexes nicht gesperrt wurde.
@item
@code{LOAD DATA INFILE} brach die Replikation ab, wenn die Datenbank aus
der Replikation ausgeschlossen war.
@item
Mehr Variablen zu @code{SHOW SLAVE STATUS} und @code{SHOW MASTER STATUS}
hinzugefügt.
@item
@code{SLAVE STOP} gibt jetzt solange nichts zurück, bis der Thread
tatsächlich beendet ist.
@item
Volltextsuche mit der @code{MATCH}-Funktion und @code{FULLTEXT}-Indextyp
hinzugefügt (für MyISAM-Dateien). Das macht @code{FULLTEXT} zu einem
reservierten Wort.
@end itemize


@node News-3.23.22, News-3.23.21, News-3.23.23, News-3.23.x
@c German node Neuigkeiten-3.23.22
@appendixsubsec Änderungen in Release 3.23.22

@itemize @bullet
@item
@code{lex_hash.h} wird jetzt für jede MySQL-Distribution korrekt erzeugt.
@item
@code{MASTER} und @code{COLLECTION} sind jetzt reservierte Wörter.
@item
Die Log-Datei, die von @code{--slow-query-log} erzeugt wird, enthielt nicht
die gesamten Anfragen.
@item
Offene Transaktionen in BDB-Tabellen werden jetzt nicht mehr zurückgerollt,
wenn die Verbindung unerwartet geschlossen wird.
@item
Workaround für einen Bug in @code{gcc} 2.96 (intel) und @code{gcc} 2.9
(Ia64) in @code{gen_lex_hash.c} hinzugefügt.
@item
Speicherleck in der Client-Bibliothek bei der Benutzung von @code{host=} in
der @code{my.cnf}-Datei behoben.
@item
Funktionen optimiert, die Stunden/Minuten/Sekunden bearbeiten.
@item
Bug beim Vergleich des Ergebnisses von @code{DATE_ADD()}/@code{DATE_SUB()}
mit einer Zahl behoben.
@item
Bedeutung von @code{-F, --fast} für @code{myisamchk} geändert. Option
@code{-C, --check-only-changed} für @code{myisamchk} hinzugefügt.
@item
@code{ANALYZE tabelle} zum Aktualisieren von Schlüsselstatistiken für
Tabellen hinzugefügt.
@item
Binäreinheiten @code{0x...} abgeändert, so dass sie vorgabemäßig als
Ganzzahlen betrachtet werden.
@item
Fehlerbehebung für SCO und @code{SHOW PROCESSLIST}.
@item
@code{auto-rehash} beim erneuten Verbinden für den @code{mysql}-Client
hinzugefügt.
@item
Neu eingeführten Bug in @code{MyISAM} behoben, bei dem die Index-Datei
nicht größer als 64 MB werden durfte.
@item
@code{SHOW MASTER STATUS} und @code{SHOW SLAVE STATUS} hinzugefügt.
@end itemize


@node News-3.23.21, News-3.23.20, News-3.23.22, News-3.23.x
@c German node Neuigkeiten-3.23.21
@appendixsubsec Änderungen in Release 3.23.21

@itemize @bullet
@item
@code{mysql_character_set_name(MYSQL *mysql)}-Funktion zur MySQL-C-API
hinzugefügt.
@item
Update-Log-Datei @code{ASCII 0}-sicher gemacht.
@item
@code{mysql_config}-Skript hinzugefügt.
@item
Problem bei der Benutzung von @code{<} oder @code{>} mit einer CHAR-Spalte,
die nur teilweise indexiert war, behoben.
@item
Man erhielt einen Coredump, wenn die Log-Datei nicht vom MySQL-Benutzer
lesbar war.
@item
@code{mysqladmin} so geändert, dass es die @code{CREATE
DATABASE}/@code{DROP DATABASE}-Befehle anstelle der alten, nicht
empfohlenen API-Aufrufe benutzt.
@item
@code{chown}-Warnung in @code{safe_mysqld} in Ordnung gebracht.
@item
Bug in @code{ORDER BY} behoben, der in Version 3.23.19 eingeführt wurde.
@item
@code{DELETE FROM tabelle} wird nur dann optimiert, ein Löschen und
Neuerzeugen der Tabelle auszuführen, wenn man sich im
@code{AUTOCOMMIT}-Modus befindet (benötigt für BDB-Tabellen).
@item
Zusätzliche Prüfungen hinzugefügt, um Index-Beschädigung zu vermeiden, wenn
die @code{ISAM}/@code{MyISAM}-Index-Dateien während eines
@code{INSERT}/@code{UPDATE} voll werden.
@item
@code{myisamchk} aktualisierte die Zeilenprüfsumme nicht korrekt, wenn es
mit @code{-ro} benutzt wurde (sondern gab nur bei nachfolgenden Läufen eine
Warnung aus).
@item
Bug in @code{REPAIR TABLE} behoben, so dass es bei Tabellen ohne Indexe
funktioniert.
@item
Puffer-Überlauf in @code{DROP DATABASE} behoben.
@item
@code{LOAD TABLE FROM MASTER} ist ausreichend ohne Bugs, um es als Feature
vorstellen zu können.
@item
@code{MATCH} und @code{AGAINST} sind jetzt reservierte Wörter.
@end itemize


@node News-3.23.20, News-3.23.19, News-3.23.21, News-3.23.x
@c German node Neuigkeiten-3.23.20
@appendixsubsec Änderungen in Release 3.23.20

@itemize @bullet
@item
Bug in Version 3.23.19 behoben; @code{DELETE FROM tabelle} entfernte die
.frm-Datei.
@item
@code{SHOW CREATE TABLE}.
@end itemize


@node News-3.23.19, News-3.23.18, News-3.23.20, News-3.23.x
@c German node Neuigkeiten-3.23.19
@appendixsubsec Änderungen in Release 3.23.19

@itemize @bullet
@item
Copyright für alle Dateien zu GPL für den Server-Code und die
Dienstprogramme und LGPL für die Client-Bibliotheken geändert.
@item
Bug behoben, bei dem nicht alle übereinstimmenden Zeilen bei einer
@code{MyISAM}-Tabelle aktualisiert wurden, wenn man eine Aktualisierung
basierend auf einem Schlüssel auf eine Tabelle mit vielen Schlüsseln
durchführte, und sich einige Schlüsselwerte änderten.
@item
Die Linux-MySQL-RPMs und -Binärdateien werden jetzt bei einer
Linux-Thread-Version statisch gelinkt, die schnellere mutex-Handhabung bei
der Benutzung mit MySQL hat.
@item
@code{ORDER BY} kann jetzt @code{REF}-Schlüssel benutzen, um eine
Untermenge von Zeilen zu finden, die sortiert werden müssen.
@item
Der Name von @code{print_defaults} wurde in @code{my_print_defaults}
geändert, um Namenskonflikte zu vermeiden.
@item
@code{NULLIF()} funktioniert jetzt gemäß ANSI-SQL99.
@item
@code{net_read_timeout} und @code{net_write_timeout} als Startparameter für
@code{mysqld} hinzugefügt.
@item
Bug behoben, der den Index bei der Ausführung von @code{myisamchk
--sort-records} auf eine Tabelle mit Präfix-komprimiertem Index zerstörte.
@item
pack_isam und myisampack zur Standard-MySQL-Distribution hinzugefügt.
@item
Die Syntax @code{BEGIN WORK} hinzugefügt (dasselbe wie @code{BEGIN}).
@item
Coredump-Bug bei der Benutzung von @code{ORDER BY} auf
@code{CONV()}-Ausdruck behoben.
@item @code{LOAD TABLE FROM MASTER} hinzugefügt.
@item @code{FLUSH MASTER} und @code{FLUSH SLAVE} hinzugefügt.
@item Großes/kleines 'endian'-Problem in der Replikation behoben.
@end itemize


@node News-3.23.18, News-3.23.17, News-3.23.19, News-3.23.x
@c German node Neuigkeiten-3.23.18
@appendixsubsec Änderungen in Release 3.23.18

@itemize @bullet
@item
Problem aus Version 3.23.17 bei der Auswahl eines Zeichensatzes auf der
Client-Seite behoben.
@item
@code{FLUSH TABLES with READ LOCK} geändert, so dass es eine globale Sperre
macht, die für das Herstellen einer Kopie der MySQL-Daten-Dateien geeignet
ist.
@item
@code{CREATE TABLE ... SELECT ... PROCEDURE} funktioniert jetzt.
@item
Interne temporäre Tabellen benutzen jetzt einen komprimierten Index bei der
Benutzung von @code{GROUP BY} auf @code{VARCHAR/CHAR}-Spalten.
@item
Problem behoben beim Sperren derselbe Tabelle mit einer @code{READ}- und
einer @code{WRITE}-Sperre.
@item
Problem mit myisamchk und @code{RAID}-Tabellen behoben.
@end itemize


@node News-3.23.17, News-3.23.16, News-3.23.18, News-3.23.x
@c German node Neuigkeiten-3.23.17
@appendixsubsec Änderungen in Release 3.23.17

@itemize @bullet
@item
Bug in @code{find_in_set()} behoben, wenn das erste Argument @code{NULL}
war.
@item
Tabellensperren für Berkeley-DB hinzugefügt.
@item
Bug bei @code{LEFT JOIN} und @code{ORDER BY} behoben, bei dem die erste
Tabelle nur eine übereinstimmende Zeile hatte.
@item
4 @code{my.cnf}-Beispiel-Dateien im @file{Support-files}-Verzeichnis
hinzugefügt.
@item
@code{duplicated key}-Problem bei der Ausführung großer @code{GROUP BY}s
behoben. (Dieser Bug wurde wahrscheinlich in Version 3.23.15 eingeführt).
@item
Syntax für @code{INNER JOIN} geändert, um ANSI-SQL zu entsprechen.
@item
@code{NATURAL JOIN}-Syntax hinzugefügt.
@item
Viele Korrekturen in der @code{BDB}-Schnittstelle.
@item
Handhabung von @code{--no-defaults} und @code{--defaults-file} für
@code{safe_mysqld.sh} und @code{mysql_install_db.sh} hinzugefügt.
@item
Bug beim Lesen komprimierter Tabellen mit vielen Threads behoben.
@item
@code{USE INDEX} funktioniert jetzt mit @code{PRIMARY}-Schlüsseln.
@item
@code{BEGIN}-Statement geändert, so dass es eine Transaktion im
@code{AUTOCOMMIT}-Modus startet.
@item
Symbolische-Links-Unterstützung für Windows.
@item
Protokoll geändert, so dass der Client weiß, ob der Server im AUTOCOMMIT-
Modus ist und ob es eine anhängige Transaktion gibt. Wenn das der Fall ist,
gibt die Client-Bibliothek einen Fehler aus, bevor sie sich wieder mit dem
Server verbindet, damit der Client weiß, dass der Server ein Rollback
durchgeführt hat. Das Protokoll ist noch abwärtskompatibel mit den alten
Clients.
@item
@code{KILL} funktioniert jetzt auf einem Thread, der durch ein 'Schreiben'
auf einen toten Client gesperrt ist.
@item
Speicherleck im Replikations-Slave-Thread behoben.
@item
Neue Option @code{log-slave-updates} hinzugefügt, die das
Hintereinanderhängen im Kreis (Daisy-Chaining, 'Ringelrei') von Slaves
erlaubt.
@item
Compile-Fehler auf FreeBSD und anderen Systemen behoben, auf denen
@code{pthread_t} nicht dasselbe wie @code{int} ist.
@item
Herunterfahren des Masters bricht den Slave-Thread nicht mehr ab.
@item
Race-Bedingung im @code{INSERT DELAYED}-Code beim Ausführen von @code{ALTER
TABLE} behoben.
@item
Blockierungsüberprüfung für @code{INSERT DELAYED} hinzugefügt.
@end itemize


@node News-3.23.16, News-3.23.15, News-3.23.17, News-3.23.x
@c German node Neuigkeiten-3.23.16
@appendixsubsec Änderungen in Release 3.23.16

@itemize @bullet
@item
Option @code{TYPE=QUICK} für @code{CHECK} und @code{REPAIR} hinzugefügt.
@item
Bug in @code{REPAIR TABLE} behoben, wenn die Tabelle durch einen anderen
Thread in Benutzung war.
@item
Einen Thread-Cache hinzugefügt, um zu ermöglichen, MySQL mit @code{gdb} zu
debuggen, wenn man viele erneute Verbindungen durchführt. Das verbessert
auch Systeme, auf denen man keine persistenten Verbindungen benutzen kann.
@item
Viele Korrekturen in der Berkeley-DB-Schnittstelle.
@item
@code{UPDATE IGNORE} bricht jetzt nicht mehr ab, wenn eine Aktualisierung
zu einem @code{DUPLICATE_KEY}-Fehler führt.
@item
@code{CREATE TEMPORARY TABLE}-Befehle werden in die Update-Log-Datei
geschrieben.
@item
Bug bei der Handhabung von maskierten IP-Nummern in den
Berechtigungstabellen behoben.
@item
Bug mit @code{delayed_key_writes}-Tabellen und @code{CHECK TABLE} behoben.
@item
@code{replicate-do-db} und @code{replicate-ignore-db}-Optionen hinzugefügt,
um auf Datenbanken zu beschränken, die repliziert werden.
@item
@code{SQL_LOG_BIN}-Option hinzugefügt.
@end itemize


@node News-3.23.15, News-3.23.14, News-3.23.16, News-3.23.x
@c German node Neuigkeiten-3.23.15
@appendixsubsec Änderungen in Release 3.23.15

@itemize @bullet
@item
Um @code{mysqld} als @code{root} zu starten, müssen Sie jetzt die @code{--
user=root}-Option benutzen.
@item
Schnittstelle zu Berkeley-DB hinzugefügt. (Diese funktioniert noch nicht
richtig. Spielen Sie mit ihr auf eigenes Risiko herum!)
@item
Replikation zwischen Master und Slaves hinzugefügt.
@item
Bug behoben, bei dem ein anderer Thread eine Sperre stehlen konnte, wenn
ein Thread eine Sperre auf eine Tabelle hatte und einen @code{FLUSH
TABLES}-Befehl ausführte.
@item
Die @code{slow_launch_time}-Variable und die
@code{slow_launch_thread}-Status-Variable zu @code{mysqld} hinzugefügt.
Diese können mit @code{mysqladmin variables} und @code{mysqladmin
extended-status} betrachtet werden.
@item
Funktionen @code{INET_NTOA()} und @code{INET_ATON()} hinzugefügt.
@item
Der vorgabemäßige Typ von @code{IF()} hängt jetzt vom zweiten und dritten
Argument ab und nicht nur vom zweiten.
@item
Fall behoben, bei dem @code{myisamchk} beim Versuch, eine Tabelle zu
reparieren, in eine Schleife geraten konnte.
@item
@code{INSERT DELAYED} nicht in die Update-Log-Datei schreiben, wenn
@code{SQL_LOG_UPDATE=0}.
@item
Problem mit @code{REPLACE} auf @code{HEAP}-Tabellen behoben.
@item
Mögliche Zeichensätze und Zeitzone zu @code{SHOW VARIABLES} hinzugefügt.
@item
Bug im Sperr-Code behoben, der zu Sperrproblemen bei gleichzeitigen
Einfügevorgängen unter hoher Last führen konnte.
@item
Problem bei @code{DELETE} vieler Zeilen auf eine Tabelle mit komprimierten
Schlüsseln behoben, bei dem MySQL den Index scannte, um Zeilen zu finden.
@item
Problem mit @code{CHECK} auf Tabelle mit gelöschten Schlüsselblöcken
behoben.
@item
Bug beim Neuverbinden (auf der Client-Seite) behoben, bei dem in manchen
Situationen Speicher nicht freigegeben wurde.
@item
Probleme in der Update-Log-Datei bei der Benutzung von
@code{LAST_INSERT_ID()} zum Aktualisieren einer Tabelle mit einem
auto_increment-Schlüssel behoben.
@item
Funktion @code{NULLIF()} hinzugefügt.
@item
Bug bei der Benutzung von @code{LOAD DATA INFILE} auf eine Tabelle mit
@code{BLOB/TEXT}-Spalten behoben.
@item
MyISAM optimiert, um es beim Einfügen von Schlüsseln in sortierter
Reihenfolge schneller zu machen.
@item
@code{EXPLAIN SELECT ...} gibt jetzt auch aus, ob MySQL eine temporäre
Tabelle oder Dateisortieren verwendet, wenn das @code{SELECT} aufgelöst
wird.
@item
Optimierung hinzugefügt, um @code{ORDER BY}-Teile zu überspringen, bei
denen der Teil ein konstanter Ausdruck im @code{WHERE}-Teil ist. Indexe
können jetzt benutzt werden, selbst wenn das @code{ORDER BY} nicht genau
mit dem Index übereinstimmt, solange alle nicht benutzten Index-Teile und
alle zusätzlichen @code{ORDER BY}-Spalten Konstanten in der
@code{WHERE}-Klausel sind. @xref{MySQL indexes}.
@item
@code{UPDATE} und @code{DELETE} auf einen gesamten eindeutigen Schlüssel im
@code{WHERE}-Teil ist jetzt schneller als vorher.
@item
@code{RAID_CHUNKSIZE} so geändert, dass es in 1024 Bytes inkrementiert.
@item
Coredump in LOAD_FILE(NULL) behoben.
@end itemize


@node News-3.23.14, News-3.23.13, News-3.23.15, News-3.23.x
@c German node Neuigkeiten-3.23.14
@appendixsubsec Änderungen in Release 3.23.14

@itemize @bullet
@item
Bug in @code{CONCAT()} behoben, bei dem eins der Argumente eine Funktion
war, die ein verändertes Argument zurückgab.
@item
Kritischen Bug in @code{myisamchk} behoben, wobei es den Header in der
Index-Datei aktualisierte, wenn man die Tabelle nur prüfte. Das brachte den
@code{mysqld}-Daemon durcheinander, wenn er dieselbe Tabelle zur gleichen
Zeit aktualisierte. Jetzt wird der Status in der Index-Datei nur dann
aktualisiert, wenn man @code{--update-state} benutzt. Bei älteren
@code{myisamchk}-Versionen sollten Sie @code{--read-only} benutzen, wenn
Sie Tabellen nur prüfen, wenn es auch nur die geringste Chance gibt, dass
der @code{mysqld}-Server zur gleichen Zeit auf der Tabelle arbeitet!
@item
@code{DROP TABLE} wird nicht mehr in der Update-Log-Datei geloggt.
@item
Problem beim Suchen auf @code{DECIMAL()}-Schlüsselfeld behoben, wenn die
Spalte Daten mit führenden Nullen enthielt.
@item
Bug in @code{myisamchk} behoben, wenn auto_increment nicht der erste
Schlüssel ist.
@item
@code{DATETIME} wird im ISO-8601-Format zugelassen: 2000-03-12T12:00:00
@item
Dynamische Zeichensätze hinzugefügt. Eine @code{mysqld}-Binärdatei kann
jetzt viele unterschiedliche Zeichensätze handhaben (welche, können Sie
beim Start von @code{mysqld} angeben).
@item
Befehl @code{REPAIR TABLE} hinzugefügt.
@item
C-API-Funktion @code{mysql_thread_safe()} hinzugefügt.
@item
@code{UMASK_DIR}-Umgebungsvariable hinzugefügt.
@item
Funktion @code{CONNECTION_ID()} hinzugefügt.
@item
Bei der Benutzung von @code{=} auf @code{BLOB}- oder @code{VARCHAR
BINARY}-Schlüsseln, bei denen nur ein Teil der Spalte indexiert war, wurde
nicht die gesamte Spalte der Ergebniszeile verglichen.
@item
Problembehebung für sjis-Zeichensatz und @code{ORDER BY}.
@item
Beim Laufenlassen im ANSI-Modus wird nicht mehr zugelassen, dass Spalten
benutzt werden, die nicht im @code{GROUP BY}-Teil angegeben wurden.
@end itemize


@node News-3.23.13, News-3.23.12, News-3.23.14, News-3.23.x
@c German node Neuigkeiten-3.23.13
@appendixsubsec Änderungen in Release 3.23.13

@itemize @bullet
@item
Problem behoben bei der Ausführung von Sperren auf dieselbe Tabelle mehr
als zweimal im selben @code{LOCK TABLE}-Befehl. Dadurch wurde das Problem
behoben, das man bekam, wenn man test-ATIS test mit @code{--fast} oder
@code{--check-only-changed} laufen ließ.
@item
Option @code{SQL_Puffer_RESULT} für @code{SELECT} hinzugefügt.
@item
Leerzeichen am Ende von Double-/Float-Zahlen in Ergebnissen aus temporären
Tabellen entfernt.
@code{CHECK TABLE}-Befehl hinzugefügt.
@item
Änderungen für MyISAM in Version 3.23.12 hinzugefügt, die wegen
CVS-Problemen nicht in die Quelldistribution gelangten.
@item
Bug behoben, so dass @code{mysqladmin shutdown} darauf wartet, dass der
lokale Server herunter fährt.
@item
Mögliche Endlosschleife bei der Zeitstempel-Berechnung repariert.
@item
@code{print_defaults} für die @file{.rpm}-Dateien hinzugefügt.
@code{mysqlbug} aus der Client-@file{.rpm}-Datei entfernt.
@end itemize


@node News-3.23.12, News-3.23.11, News-3.23.13, News-3.23.x
@c German node Neuigkeiten-3.23.12
@appendixsubsec Änderungen in Release 3.23.12

@itemize @bullet
@item
Bug in @code{MyISAM} behoben, bei dem @code{REPLACE ... SELECT ...} eine
beschädigte Tabelle ergeben konnte.
@item
Bug in @code{myisamchk} behoben, bei dem der auto_increment-Wert falsch
zurückgesetzt wurde.
@item
VIELE Patches für Linux Alpha. MySQL scheint mittlerweile auf Linux Alpha
relativ stabil zu laufen.
@item
@code{DISTINCT} auf @code{HEAP} temporäre Tabellen so geändert, dass
gehashte Schlüssel verwendet werden, um doppelte Zeilen (Duplikate) schnell
zu finden. Das betrifft meistens Anfragen des Typs @code{SELECT DISTINCT
... GROUP BY ...}. Das behebt ein Problem, bei dem nicht alle Duplikate in
Anfragen des genannten Typs entfernt wurden. Zusätzlich ist der neue Code
VIEL schneller.
@item
Patches hinzugefügt, damit MySQL auf Mac OS X kompiliert.
@item
Option @code{IF NOT EXISTS} für @code{CREATE DATABASE} hinzugefügt.
@item
Optionen @code{--all-databases} und @code{--databases} für @code{mysqldump}
hinzugefügt, um das Dumpen vieler Datenbanken zugleich zu ermöglichen.
@item
Bug im komprimierten @code{DECIMAL()}-Index in @code{MyISAM}-Tabellen
behoben.
@item
Bug beim Speichern von 0 in ein Timestamp-Feld behoben.
@item
Beim Ausführen von @code{mysqladmin shutdown} auf eine lokale Verbindung
wartet @code{mysqladmin} jetzt, bis die PID-Datei entfernt ist, bevor es
sich beendet.
@item
Coredump bei einigen @code{COUNT(DISTINCT ...)}-Anfragen behoben.
@item
@code{myisamchk} funktioniert jetzt sauber bei RAID-Tabellen.
@item
Problem bei @code{LEFT JOIN} und @code{schluessel_feld IS NULL} behoben.
@item
Bug in @code{net_clear()} behoben, der den Fehler @code{Aborted connection}
in MySQL-Clients ausgeben konnte.
@item
Optionen @code{USE INDEX (schluessel_liste)} und @code{IGNORE INDEX
(schluessel_liste)} als Join-Parameter in @code{SELECT} hinzugefügt.
@item
@code{DELETE} und @code{RENAME} sollten jetzt auf @code{RAID}-Tabellen
funktionieren.
@end itemize


@node News-3.23.11, News-3.23.10, News-3.23.12, News-3.23.x
@c German node Neuigkeiten-3.23.11
@appendixsubsec Änderungen in Release 3.23.11

@itemize @bullet
@item
@code{ALTER TABLE tabelle ADD (feld_liste)}-Syntax wird zugelassen.
@item
Problem mit dem Optimierer behoben, der manchmal falsche Schlüssel
benutzte.
@item
@code{GRANT/REVOKE ALL PRIVILEGES} betrifft jetzt nicht mehr @code{GRANT
OPTION}.
@item
Zusätzliche Klammer (@code{)}) aus der Ausgabe von @code{SHOW GRANTS}
entfernt.
@item
Problem beim Speichern von Zahlen in Timestamps behoben.
@item
Problem mit Zeitzonen behoben, die einen Halbstunden-Offset haben.
@item
Syntax @code{UNIQUE INDEX} in @code{CREATE}-Statements wird jetzt
zugelassen.
@item
@code{mysqlhotcopy} hinzugefügt. Das ist ein schnelles
Online-Datensicherungsdienstprogramm für lokale MySQL-Datenbanken. Von Tim
Bunce.
@item
Neues, sichereres @code{mysqlaccess} hinzugefügt. Dank an Steve Harvey
hierfür.
@item
Optionen @code{--i-am-a-dummy} und @code{--safe-updates} für @code{mysql}
hinzugefügt.
@item
Variablen @code{select_limit} und @code{max_join_size} für @code{mysql}
hinzugefügt.
@item
SQL-Variablen @code{SQL_MAX_JOIN_SIZE} und @code{SQL_SAFE_UPDATES}
hinzugefügt.
@item
@code{READ LOCAL}-Sperre hinzugefügt, die die Tabelle nicht für
gleichzeitige Einfügevorgänge sperrt (das wird von @code{mysqldump}
benutzt).
@item
@code{LOCK TABLES ... READ} läßt keine gleichzeitigen Einfügevorgänge mehr
zu.
@item
Option @code{--skip-delay-key-write} für @code{mysqld} hinzugefügt.
@item
Sicherheitsproblem im Protokoll betreffend Passwortüberprüfung behoben.
@item
@code{_rowid} kann jetzt als Alias für eine eindeutig indexierte Spalte vom
Typ Ganzzahl benutzt werden.
@item
Zurück-Blockieren (Back Blocking) für @code{SIGPIPE} beim Kompilieren mit
@code{--thread-safe-clients} hinzugefügt, um Dinge für alte Clients sicher
zu machen.
@end itemize


@node News-3.23.10, News-3.23.9, News-3.23.11, News-3.23.x
@c German node Neuigkeiten-3.23.10
@appendixsubsec Änderungen in Release 3.23.10

@itemize @bullet
@item
Bug in Version 3.23.9 behoben, bei dem Speicher nicht korrekt freigegeben
wurde, wenn man @code{LOCK TABLES} ausführte.
@end itemize


@node News-3.23.9, News-3.23.8, News-3.23.10, News-3.23.x
@c German node Neuigkeiten-3.23.9
@appendixsubsec Änderungen in Release 3.23.9

@itemize @bullet
@item
Problem behoben, dass betroffene Anfragen Berechnungen auf
Gruppenfunktionen durchführten.
@item
Problem mit timestamps und @code{INSERT DELAYED} behoben.
@item
@code{datum_spalte BETWEEN konstanten_datum AND konstanten_datum}
funktioniert.
@item
Problem behoben, wenn man nur eine 0 zu @code{NULL} in einer Tabelle mit
@code{BLOB/TEXT}-Spalten änderte.
@item
Bug im Bereichsoptimierer bei der Benutzung von vielen Schlüsselteilen und
/ oder den mittleren Schlüsselteilen behoben: @code{WHERE K1=1 and K3=2 and
(K2=2 and K4=4 or K2=3 and K4=5)}
@item
Befehl @code{source} für @code{mysql} hinzugefügt, um Lesen von
Stapeldateien innerhalb des @code{mysql}-Clients zu ermöglichen.
Original-Patch von Matthew Vanecek.
@item
Kritisches Problem mit der @code{WITH GRANT OPTION}-Option behoben.
@item
Keinen unnötigen @code{GRANT}-Fehler bei der Benutzung von Tabellen von
vielen Datenbanken in derselben Anfrage ausgeben.
@item
VIO-Wrapper (benötigt für SSL-Unterstützung) hinzugefügt. Von Andrei
Errapart und Tõnu Samuel).
@item
Optimiererproblem bei @code{SELECT} bei der Benutzung von vielen
überlappenden Indexen behoben. MySQL sollte jetzt in der Lage sein,
Schlüssel noch besser auszusuchen, wenn es viele Schlüssel zur Auswahl
gibt.
@item
Optimierer so geändert, dass er einen Bereichsschlüssel anstelle eines
Verweisschlüssels bevorzugt, wenn der Bereichsschlüssel mehr Spalten als
der Verweisschlüssel benutzen kann (der nur Spalten mit = verwenden
kann). Folgender Anfragentyp beispielsweise sollte jetzt schneller sein:
@code{SELECT * from schluessel_teil_1=konstante und schluessel_teil_2 >
konstante2}
@item
Bug behoben, bei dem eine Änderung aller @code{VARCHAR}-Spalten in
@code{CHAR}-Spalten den Spaltentyp nicht von dynamisch auf fest änderte.
@item
Fließkomma-Ausnahmefehler für FreeBSD abgeschaltet, um Coredump beim
Ausführen von @code{SELECT floor(pow(2,63))} zu vermeiden.
@item
@code{mysqld}-Startoption @code{--delay-key-write} in
@code{--delay-key-write-for-all-tables} geändert.
@item
@code{read-next-on-key} für @code{HEAP}-Tabellen hinzugefügt. Das sollte
alle Probleme mit @code{HEAP}-Tabellen bei der Benutzung von
Nicht-@code{UNIQUE}-Schlüsseln beheben.
@item
Optionen für die Ausgabe vorgabemäßiger Argumente für alle Clients
hinzugefügt.
@item
@code{--log-slow-queries} für @code{mysqld} hinzugefügt, um alle Anfragen
in einer separate Log-Datei zu loggen, die lange dauerten, mit einer
Zeitangabe, wie lange die Anfrage benötigte.
@item
Coredump bei der Ausführung von @code{WHERE schluessel_spalte=RAND(...)}
behoben.
@item
Optimierungs-Bug in @code{SELECT ... LEFT JOIN ... schluessel_spalte IS
NULL} behoben, wenn @code{schluessel_spalte} @code{NULL}-Werte enthalten
konnte.
@item
Problem mit 8-Bit-Zeichen als Trennzeichen in @code{LOAD DATA INFILE}
behoben.
@end itemize


@node News-3.23.8, News-3.23.7, News-3.23.9, News-3.23.x
@c German node Neuigkeiten-3.23.8
@appendixsubsec Änderungen in Release 3.23.8

@itemize @bullet
@item
Problem bei der Handhabung von Index-Dateien größer als 8 GB behoben.
@item
neueste Patches für mit-pThread für NetBSD angewandt.
@item
Probleme mit Zeitzonen < GMT - 11 behoben.
@item
Bug beim Löschen komprimierter Schlüssel in @code{MyISAM} behoben.
@item
Problem mit @code{ISAM} bei der Ausführung einiger @code{ORDER BY ...
DESC}-Anfragen behoben.
@item
Bug bei der Ausführung eines Joins auf einen Text-Schlüssel behoben, der
nicht den gesamten Schlüssel abdeckte.
@item
Option @code{--delay-key-write} schaltete verzögertes Schlüssel-Schreiben
nicht an.
@item
Aktualisierung von @code{TEXT}-Spalten, die nur Änderungen der
Groß-/Kleinschreibung beinhalteten, in Ordnung gebracht.
@item
@code{INSERT DELAYED} aktualisiert jetzt Timestamps, die angegeben sind.
@item
Funktion @code{YEARWEEK()} und Optionen @code{x}, @code{X}, @code{v} und
@code{V} für @code{DATE_FORMAT()} hinzugefügt.
@item
Problem mit @code{MAX(indexierte_spalte)} und HEAP-Tabellen behoben.
@item
Problem mit @code{BLOB NULL}-Schlüsseln und @code{LIKE} "praefix%"
behoben.
@item
Problem mit @code{MyISAM} und Zeilen fester Länge < 5 Bytes behoben.
@item
Problem behoben, bei dem es vorkommen konnte, dass MySQL auf freigegebenen
Speicher zugriff, wenn er sehr komplizierte @code{GROUP BY}-Anfragen
ausführte.
@item
Coredump behoben, wenn man eine beschädigte Tabelle erhielt, in der ein
@code{ENUM}-Feldwert zu Groß war.
@end itemize


@node News-3.23.7, News-3.23.6, News-3.23.8, News-3.23.x
@c German node Neuigkeiten-3.23.7
@appendixsubsec Änderungen in Release 3.23.7

@itemize @bullet
@item
Workaround unter Linux in Ordnung gebracht, um Probleme mit
@code{pthread_mutex_timedwait}, was bei @code{INSERT DELAYED} benutzt wird,
zu vermeiden. @xref{Linux}.
@item
Man erhält jetzt einen 'disk full'-Fehler, wenn die Festplatten beim
Sortieren voll wird (statt darauf zu warten, bis mehr Plattenplatz
verfügbar ist).
@item
Bug in @code{MyISAM} mit Schlüsseln > 250 Zeichen behoben.
@item
In @code{MyISAM} kann man jetzt ein @code{INSERT} zur selben Zeit
durchführen, in der andere Threads aus der Tabelle lesen.
@item
Variable @code{max_write_lock_count} für @code{mysqld} hinzugefügt, um eine
@code{READ}-Sperre nach einer bestimmten Anzahl von @code{WRITE}-Sperren zu
erzwingen.
@item
Flag @code{delayed_key_write} bei @code{show variables} invertiert.
@item
Variable @code{concurrency} in @code{thread_concurrency} umbenannt.
@item
Folgende Funktionen sind jetzt Multi-Byte-sicher:
@code{LOCATE(teilzeichenfolge,zeichenkette)},
@code{POSITION(teilzeichenfolge IN zeichenkette)},
@code{LOCATE(teilzeichenfolge,zeichenkette,position)},
@code{INSTR(zeichenkette,teilzeichenfolge)},
@code{LEFT(zeichenkette,laenge)}, @code{RIGHT(zeichenkette,laenge)},
@code{SUBSTRING(zeichenkette,pos,laenge)}, @code{SUBSTRING(zeichenkette
FROM position FOR laenge)}, @code{MID(zeichenkette,position,laenge)},
@code{SUBSTRING(zeichenkette,position)}, @code{SUBSTRING(zeichenkette FROM
pos)}, @code{SUBSTRING_INDEX(zeichenkette,begrenzer,zaehler)},
@code{RTRIM(zeichenkette)}, @code{TRIM([[BOTH | TRAILING]
[entfernzeichenkette] FROM] zeichenkette)},
@code{REPLACE(zeichenkette,from_zeichenkette,to_zeichenkette)},
@code{REVERSE(zeichenkette)},
@code{INSERT(zeichenkette,pos,laenge,newstr)}, @code{LCASE(zeichenkette)},
@code{LOWER(zeichenkette)}, @code{UCASE(zeichenkette)} und
@code{UPPER(zeichenkette)}. Patch von Wei He.
@item
Coredump beim Aufheben einer Sperre von einer nicht existierenden Tabelle
behoben.
@item
Sperren auf Tabellen werden jetzt entfernt, bevor Duplikate entfernt
werden.
@item
Option @code{FULL} für @code{SHOW PROCESSLIST} hinzugefügt.
@item
Option @code{--verbose} für @code{mysqladmin} hinzugefügt.
@item
Problem beim automatischen Umwandeln von HEAP in MyISAM behoben.
@item
Bug in HEAP-Tabellen behoben, wenn man INSERT + DELETE + INSERT + Scannen
der Tabelle ausführt.
@item
Bugs auf Alpha mit @code{REPLACE()} und @code{LOAD DATA INFILE} behoben.
@item
@code{mysqld}-Variable @code{interactive_timeout} hinzugefügt.
@item
Argument für @code{mysql_data_seek()} von @code{ulong} zu @code{ulonglong}
geändert.
@end itemize


@node News-3.23.6, News-3.23.5, News-3.23.7, News-3.23.x
@c German node Neuigkeiten-3.23.6
@appendixsubsec Änderungen in Release 3.23.6

@itemize @bullet
@item
@code{mysqld}-Option @code{-O lower_case_tables=@{0|1@}} hinzugefügt, damit
Benutzer Tabellennamen to Kleinschreibung erzwingen können.
@item
@code{SELECT ... INTO DUMPFILE} hinzugefügt.
@item
@code{mysqld}-Option @code{--ansi} hinzugefügt, um einige Funktionen
@code{ANSI-SQL}-kompatibler zu machen.
@item
Temporäre Tabellen fangen jetzt mit @code{#sql} an.
@item
Quoten von Bezeichnern mit @code{`} (@code{"} im @code{--ansi}-Modus).
@item
Jetzt wird snprintf() bei der Ausgabe von Fließkommazahlen benutzt, um
einige Puffer-Überläufe unter FreeBSD zu vermeiden.
@item
@code{[floor()} überlaufsicher unter FreeBSD gemacht.
@item
Option @code{--quote-names} für @code{mysqldump} hinzugefügt.
@item
Bug behoben, dass man einen Teil eines @code{PRIMARY KEY NOT NULL} machen
konnte.
@item
@code{encrypt()} in Ordnung gebracht, um Thread-sicher zu sein und Puffer
nicht erneut zu benutzen.
@item
@code{mysql_odbc_escape_string()}-Funktion zur Unterstützung von
big5-Zeichen in MyODBC hinzugefügt.
@item
Die Tabellen-Handler wurden umgeschrieben und benutzen jetzt Klassen.
Hierdurch wird viel neuer Code eingeführt, aber die Tabellenhandhabung wird
schneller und besser.
@item
Patch von Sasha für benutzerdefinierte Variablen angewandt.
@item
@code{FLOAT} und @code{DOUBLE} (ohne jeden Längen-Modifikator) sind jetzt
keine festen Dezimalpunkt-Zahlen mehr.
@item
Die Bedeutung von @code{FLOAT(X)} wurde geändert: Jetzt ist das dasselbe
wie @code{FLOAT}, wenn X <= 24, und @code{DOUBLE}, wenn 24 < X <= 53.
@item
@code{DECIMAL(X)} ist jetzt ein Alias für @code{DECIMAL(X,0)}, und
@code{DECIMAL} ist jetzt ein Alias für @code{DECIMAL(10,0)}. Dasselbe gilt
für @code{NUMERIC}.
@item
Option @code{ROW_FORMAT=@{default | dynamic | static | compressed@}} für
@code{CREATE_TABLE} hinzugefügt.
@item
@code{DELETE FROM tabelle} funktionierte nicht auf temporären Tabellen.
@item
Funktion @code{CHAR_LENGTH()} geändert, so dass sie
Multi-Byte-Zeichen-sicher ist.
@item
Funktion @code{ORD(zeichenkette)} hinzugefügt.
@end itemize


@node News-3.23.5, News-3.23.4, News-3.23.6, News-3.23.x
@c German node Neuigkeiten-3.23.5
@appendixsubsec Änderungen in Release 3.23.5

@itemize @bullet
@item
Einige Jahr-2000-Probleme in der neuen Daten-Handhabung in Version 3.23
behoben.
@item
Problem mit @code{SELECT DISTINCT ... ORDER BY RAND()} behoben.
@item
Patches von Sergei A. Golubchik für Textsuche auf MyISAM-Ebene angewandt.
@item
Cache-Überlaufproblem bei der Benutzung von Full Joins ohne Schlüssel
behoben.
@item
Einige configure-Probleme bereinigt.
@item
Einige kleine Änderungen, um das Parsen schneller zu machen.
@item
@code{ALTER TABLE} + Hinzufügen einer Spalte nach dem letzten Feld
funktionierte nicht.
@item
Problem bei der Benutzung einer auto_increment-Spalte in zwei Schlüsseln
behoben.
@item
Bei MyISAM kann man jetzt den auto_increment-Teil als Untermenge haben:
@code{CREATE TABLE foo (a int not null auto_increment, b char(5), primary
key (b,a))}
@item
Bug in MyISAM mit komprimierten CHAR-Schlüsseln, die @code{NULL} sein
konnten, behoben.
@item
@code{AS} auf Feldname mit @code{CREATE TABLE tabelle SELECT ...}
funktionierte nicht.
@item
Benutzung von @code{NATIONAL} und @code{NCHAR} bei der Definition von
Zeichenspalten wird zugelassen. Das ist dasselbe, als wenn man
@code{BINARY} nicht benutzt.
@item
Keine @code{NULL}-Spalten in einem @code{PRIMARY KEY} zulassen (nur in
@code{UNIQUE}-Schlüsseln).
@item
@code{LAST_INSERT_ID} wird gelöscht (clear), wenn man diese in ODBC
benutzt: @code{WHERE auto_increment_spalte IS NULL}. Das scheint einige
Probleme mit Access zu beheben.
@item
@code{SET SQL_AUTO_IS_NULL=0|1} schaltet jetzt die Handhabung von Suchen
nach der letzten eingefügten Zeile bei @code{WHERE auto_increment_spalte IS
NULL} aus / an.
@item
Neue @code{mysqld}-Variable @code{concurrency} für Solaris hinzugefügt.
@item
Option @code{--relative} für @code{mysqladmin} hinzugefügt, um mit
@code{extended-status} eine bessere Beobachtung von Änderungen zu erzielen.
@item
Bug bei der Benutzung von @code{COUNT(DISTINCT ...)} auf eine leere Tabelle
behoben.
@item
Unterstützung für den chinesischen Zeichensatz GBK hinzugefügt.
@item
Problem mit @code{LOAD DATA INFILE} und @code{BLOB}-Spalten behoben.
@item
Bit-Operator @code{~} (Negation) hinzugefügt.
@item
Problem mit @code{UDF}-Funktionen behoben.
@end itemize


@node News-3.23.4, News-3.23.3, News-3.23.5, News-3.23.x
@c German node Neuigkeiten-3.23.4
@appendixsubsec Änderungen in Release 3.23.4

@itemize @bullet
@item
Einfügen eines @code{DATETIME}-Werts in eine @code{TIME}-Spalte versucht
jetzt nicht mehr, darin 'Tage' zu speichern.
@item
Problem mit der Speicherung von Float / Double auf kleinen Endian-Maschinen
behoben (das betraf @code{SUM()}).
@item
Verbindungs-Zeitüberschreitung (Timeout) auf TCP/IP-Verbindungen
hinzugefügt.
@item
Problem mit @code{LIKE} "%" auf einem Index, der @code{NULL}-Werte
enthalten darf, behoben.
@item
@code{REVOKE ALL PRIVILEGES} widerrief nicht alle Berechtigungen.
@item
Erzeugung temporärer Tabellen mit demselben Namen wie die Original-Tabelle
wird zugelassen.
@item
Wenn man einem Benutzer eine Berechtigungsoption (Grant Option) für eine
Datenbank gewährte, konnte er die Berechtigungen nicht an andere Benutzer
weitergeben.
@item
Neuer Befehl @code{SHOW GRANTS FOR benutzer} hinzugefügt (von Sinisa).
@item
Neue @code{date_add}-Syntax @code{date/datetime + INTERVAL # intervall_typ}
hinzugefügt. Von Joshua Chamas.
@item
Berechtigungsüberprüfung für @code{LOAD DATA REPLACE} in Ordnung gebracht.
@item
Automatische Reparatur beschädigter Include-Dateien auf Solaris 2.7
hinzugefügt.
@item
Einige configure-Probleme behoben, um Probleme bei der Erkennung großer
Dateisysteme zu beheben.
@item
@code{REGEXP} ist jetzt unabhängig von der verwendeten
Groß-/Kleinschreibung, wenn Sie nicht binäre Zeichenketten verwenden.
@end itemize


@node News-3.23.3, News-3.23.2, News-3.23.4, News-3.23.x
@c German node Neuigkeiten-3.23.3
@appendixsubsec Änderungen in Release 3.23.3

@itemize @bullet
@item
Patches für MIT-pThread auf NetBSD angewandt.
@item
Bereichs-Bug in MyISAM behoben.
@item
@code{ASC} ist jetzt wieder Vorgabe für @code{ORDER BY}.
@item
@code{LIMIT} für @code{UPDATE} hinzugefügt.
@item
Neue Client-Funktion @code{mysql_change_user()} hinzugefügt.
@item
Zeichensatz zu @code{SHOW VARIABLES} hinzugefügt.
@item
Unterstützung von @code{--[leerraum]}-Kommentaren hinzugefügt.
@item
@code{INSERT into tabelle VALUES ()} wird zugelassen. Das heißt, Sie
können jetzt eine leere Wertliste angeben, die in eine Zeile eingefügt
wird, und in der jede Spalte auf ihren Vorgabewert gesetzt wird.
@item
@code{SUBSTRING(text FROM position)} geändert, um ANSI-SQL-kompatibel zu
sein. (Vorher gab dieses Konstrukt das rechteste 'position'-Zeichen
zurück.)
@item
@code{SUM()} mit @code{GROUP BY} gab auf manchen Systemen 0 zurück.
@item
Ausgabe bei @code{SHOW TABLE STATUS} geändert.
@item
@code{DELAY_KEY_WRITE}-Option für @code{CREATE TABLE} hinzugefügt.
@item
@code{AUTO_INCREMENT} wird für jeden beliebigen Schlüsselteil zugelassen.
@item
Problem mit @code{YEAR(NOW())} und @code{YEAR(CURDATE())} behoben.
@item
@code{CASE}-Konstrukt hinzugefügt.
@item
Neue Funktion @code{COALESCE()} hinzugefügt.
@end itemize


@node News-3.23.2, News-3.23.1, News-3.23.3, News-3.23.x
@c German node Neuigkeiten-3.23.2
@appendixsubsec Änderungen in Release 3.23.2

@itemize @bullet
@item
Bereichsoptimierer-Bug behoben: @code{SELECT * FROM tabelle WHERE
schluessel_teil1 >= konstante AND (schluessel_teil2 = konstante OR
schluessel_teil2 = konstante)}. Der Bug bestand darin, dass manche Zeilen
im Ergebnis doppelt auftauchen konnten.
@item
Das Laufenlassen von @code{myisamchk} ohne @code{-a} aktualisierte die
Index-Verteilung falsch.
@item
@code{SET SQL_LOW_PRIORITY_UPDATES=1} gab vorher einen Parser-Fehler.
@item
Sie können jetzt Spalten indexieren, die in der @code{WHERE}-Klausel
benutzt werden. @code{UPDATE tabelle SET KEY=KEY+1 WHERE KEY > 100}
@item
Datums-Handhabung sollte jetzt etwas schneller sein.
@item
Handhabung von 'fuzzy' Datumsangaben möglich (Datumsangaben, bei denen der
Tag oder der Monat 0 sind, wie 1999-01-00).
@item
Optimierung von @code{SELECT ... WHERE schluessel_teil1=konstante1 AND
schluessel_teil_2=konstante2 AND schluessel_teil1=konstante4 AND
schluessel_teil2=konstante4} in Ordnung gebracht. Indextyp sollte
@code{range} anstelle von @code{ref} sein.
@item
@code{egcs}-1.1.2-Optimierer-Bug behoben (bei der Benutzung von
@code{BLOB}s) auf Linux Alpha.
@item
Problem mit @code{LOCK TABLES} in Kombination mit @code{DELETE FROM
tabelle} behoben.
@item
MyISAM-Tabellen lassen jetzt Schlüssel auf @code{NULL} und
@code{BLOB/TEXT}-Spalten zu.
@item
Folgender Join ist jetzt viel schneller: @code{SELECT ... FROM t1 LEFT JOIN
t2 ON ... WHERE t2.nicht_null_spalte IS NULL}.
@item
@code{ORDER BY} und @code{GROUP BY} können jetzt auf Funktionen angewendet
werden.
@item
Handhabung von 'konstante' geändert, um Handhabung von @code{ORDER BY
RAND()} zu gestatten.
@item
Indexe werden jetzt für @code{WHERE schluessel_spalte = funktion} benutzt.
@item
Indexe werden jetzt für @code{WHERE schluessel_spalte = spalten_name}
benutzt, selbst wenn die Spalten nicht identisch komprimiert sind.
@item
Indexe werden jetzt für @code{WHERE spalten_name IS NULL} benutzt.
@item
HEAP-Tabellen so geändert, dass in der Reihenfolge niedriges Byte zuerst
gespeichert wird (um es zu erleichtern, MyISAM-Tabellen zu konvertieren).
@item
Automatische Änderung temporärer HEAP-Tabellen in MyISAM-Tabellen im Falle
von 'table is full'-Fehlern.
@item
Option @code{--init-file=datei} für @code{mysqld} hinzugefügt.
@item
@code{COUNT(DISTINCT wert, [wert, ...])} hinzugefügt.
@item
@code{CREATE TEMPORARY TABLE} erzeugt jetzt eine temporäre Tabelle in ihrem
eigenen Namensraum, die automatisch gelöscht wird, wenn die Verbindung
beendet wird.
@item
Neue reservierte Wörter (erforderlich für @code{CASE}): @code{CASE, THEN,
WHEN, ELSE und END}.
@item
Neue Funktionen @code{EXPORT_SET()} und @code{MD5()} hinzugefügt.
@item
Unterstützung für den GB2312 chinesischen Zeichensatz hinzugefügt.
@end itemize


@node News-3.23.1, News-3.23.0, News-3.23.2, News-3.23.x
@c German node Neuigkeiten-3.23.1
@appendixsubsec Änderungen in Release 3.23.1

@itemize @bullet
@item
Einige Kompilierungsprobleme behoben.
@end itemize


@node News-3.23.0,  , News-3.23.1, News-3.23.x
@c German node Neuigkeiten-3.23.0
@appendixsubsec Änderungen in Release 3.23.0

@itemize @bullet
@item
Eine neue Tabellen-Handler-Bibliothek (@code{MyISAM}) mit vielen neuen
Features hinzugefügt. @xref{MyISAM}.
@item
Sie können @code{HEAP}-Tabellen im Hauptspeicher erzeugen, die zum
Nachschlagen extrem schnell sind.
@item
Unterstützung für große Dateien (63-Bit) auf Systemen, die große Dateien
unterstützen, hinzugefügt.
@item
Neue Funktion @code{LOAD_FILE(datei)} hinzugefügt, um die Inhalte einer
Datei als Zeichenkettenwert zu erhalten.
@item
Neuer Operator @code{<=>} hinzugefügt, der wie @code{=} funktioniert, aber
WAHR (true) zurückgibt, wenn beide Argumente @code{NULL} sind. Das ist
nützlich, um Änderungen zwischen Tabellen zu vergleichen.
@item
ODBC-3.0-@code{EXTRACT(intervall FROM datetime)}-Funktion hinzugefügt.
@item
Spalten, die als @code{FLOAT(X)} definiert sind, werden beim Speichern
nicht gerundet und dürfen beim Abruf in wissenschaftlicher Notation sein
(1.0 E+10).
@item
@code{REPLACE} ist jetzt schneller als vorher.
@item
@code{LIKE}-Zeichenvergleiche geändert, so dass sie sich wie @code{=}
verhalten. Das heißt, dass @code{'e' LIKE '@'é'} jetzt WAHR (true) ist
(falls hier etwas nicht richtig angezeigt wird: Das letztgenannte 'e' ist
das französische 'e' mit Akzent).
@item
@code{SHOW TABLE STATUS} gibt eine Menge an Informationen über die Tabellen
zurück.
@item
@code{LIKE} für den @code{SHOW STATUS}-Befehl hinzugefügt.
@item
Berechtigungsspalte zu @code{SHOW COLUMNS} hinzugefügt.
@item
Spalten @code{packed} und @code{comment} für @code{SHOW INDEX} hinzugefügt.
@item
Kommentare zu Tabellen (mit @code{CREATE TABLE ... COMMENT "kommentar"})
hinzugefügt.
@item
@code{UNIQUE}, wie bei @code{CREATE TABLE tabelle (spalte int not null
UNIQUE)}, hinzugefügt.
@item
Neue CREATE-Syntax: @code{CREATE TABLE tabelle SELECT ...}
@item
Neue CREATE-Syntax: @code{CREATE TABLE IF NOT EXISTS ...}
@item
Die Erzeugung von @code{CHAR(0)}-Spalten wird zugelassen.
@item
@code{DATE_FORMAT()} erfordert jetzt @samp{%} vor jeglichem
Formatierungszeichen.
@item
@code{DELAYED} ist jetzt ein reserviertes Wort (tut uns leid :( ).
@item
Eine Beispiel-Prozedur wurde hinzugefügt: @code{analyse}, Datei:
@file{sql_analyse.c}. Diese beschreibt die Daten in Ihrer Anfrage.
Probieren Sie folgendes:
@example
SELECT ... FROM ... WHERE ... prozeduranalyse([max elemente,[max speicher]])
@end example

Diese Prozedur ist extrem nützlich, wenn Sie die Daten in Ihrer Tabelle
prüfen wollen!
@item
@code{BINARY}-Cast, um zu erzwingen, dass eine Zeichenkette abhängig von
der verwendeten Groß-/Kleinschreibung verglichen wird.
@item
Option @code{--skip-show-database} für @code{mysqld} hinzugefügt.
@item
Das Prüfen, ob sich eine Zeile bei einem @code{UPDATE} geändert hat,
funktioniert jetzt auch bei @code{BLOB}-/@code{TEXT}-Spalten.
@item
Die @code{INNER}-Join-Syntax wurde hinzugefügt. @strong{HINWEIS}: Hierdurch
wurde @code{INNER} zu einem reservierten Wort!
@item
Unterstützung für Netmasks zum Hostname in den MySQL-Tabellen hinzugefügt.
Sie können eine Netmask mit der @code{IP/NETMASK}-Syntax angeben.
@item
Wenn Sie eine @code{NOT NULL DATE/DATETIME}-Spalte mit @code{IS NULL}
vergleichen, wird das zu einem Vergleich auf @code{0} geändert, um einige
ODBC-Applikationen zufrieden zu stellen (von @email{shreeve@@uci.edu}).
@item
@code{NULL IN (...)} gibt jetzt @code{NULL} anstelle von @code{0} zurück.
Das stellt sicher, dass @code{null_spalte NOT IN (...)} nicht mit
@code{NULL}-Werten übereinstimmt.
@item
Speicherung von Fließkommawerten in @code{TIME}-Spalten in Ordnung
gebracht.
@item
Das Parsen von @code{TIME}-Zeichenketten geändert, so dass es strenger ist.
Jetzt wird der Bruchteil-Sekunden-Teil erkannt (und momentan noch
übergangen). Folgende Formate werden unterstützt:
@table @code
@item [[DAYS] [H]H:]MM:]SS[.bruchteil]
@item [[[[[H]H]H]H]MM]SS[.bruchteil]
@end table
@item
Erkennen (und Ignorieren) des zweiten Bruchteil-Anteils von @code{DATETIME}
hinzugefügt.
@item
@code{LOW_PRIORITY}-Attribut für @code{LOAD DATA INFILE} hinzugefügt.
@item
Der vorgabemäßige Index-Name benutzt jetzt dieselbe Groß-/Kleinschreibung
wie der benutzte Spaltenname.
@item
Vorgabemäßige Anzahl von Verbindungen auf 100 geändert.
@item
Bei der Benutzung von @code{LOAD DATA INFILE} werden größere Puffer
verwendet.
@item
@code{DECIMAL(x,y)} funktioniert jetzt gemäß ANSI-SQL.
@item
Aggregat-UDF-Funktionen. Dank an Andreas F. Bobak @email{bobak@@relog.ch}
hierfür!
@item
@code{LAST_INSERT_ID()} wird jetzt bei @code{INSERT INTO ... SELECT}
aktualisiert.
@item
Einige kleinere Änderungen am Join-Tabellenoptimierer, um einige Joins
schneller zu machen.
@item
@code{SELECT DISTINCT} ist viel schneller. Es benutzt die neue
@code{UNIQUE}-Funktionalität in @code{MyISAM}. Ein Unterschied im Vergleich
zur MySQL-Version 3.22 besteht darin, dass die Ausgabe von @code{DISTINCT}
nicht mehr sortiert wird.
@item
Alle C-Client-API-Makros sind jetzt Funktionen, um die gemeinsam genutzten
(shared) Bibliotheken verlässlicher zu machen. Deswegen können Sie nicht
mehr @code{mysql_num_fields()} auf ein @code{MYSQL}-Objekt aufrufen,
sondern müssen statt dessen @code{mysql_field_count()} benutzen.
@item
Benutzung von @code{LIBEWRAP}; Patch von Henning P. Schmiedehausen.
@item
@code{AUTO_INCREMENT} wird nur noch für numerische Spalten zugelassen.
@item
Durch die Verwendung von @code{AUTO_INCREMENT} wird die Spalte automatisch
@code{NOT NULL}.
@item
@code{NULL} wird als Vorgabewert für AUTO_INCREMENT-Spalten angezeigt.
@item
@code{SQL_BIG_RESULT}; @code{SQL_SMALL_RESULT} ist jetzt Vorgabe.
@item
Ein gemeinsam genutztes (shared) Bibliothek-RPM hinzugefügt. Diese
Verbesserung wurde von David Fox (dsfox@@cogsci.ucsd.edu) beigesteuert.
@item
Ein @code{--enable-large-files/--disable-large-files}-Schalter zu
@code{configure} hinzugefügt. Siehe @file{configure.in} wegen mancher
Systeme, auf denen dies wegen nicht funktionierender Implementation
automatisch abgeschaltet ist.
@item
@code{readline} für Version 4.0 aktualisiert.
@item
Neue @code{CREATE TABLE}-Optionen: @code{PACK_KEYS} und @code{CHECKSUM}.
@item
@code{mysqld}-Option @code{--default-table-type} hinzugefügt.
@end itemize


@node Porting, Environment variables, News, Top
@c German node Portierung
@appendix Anmerkungen zur Portierung auf andere Systeme

@cindex Portierung, auf andere Systeme

Für den Server wird eine funktionierende Posix-Thread-Bibliothek benötigt.
Auf Solaris 2.5 benutzen wir Sun PThread (die native Thread-Unterstützung
in Version 2.4 und früher ist nicht gut genug). Auf Linux benutzen wir
LinuxThread von Xavier Leroy, @email{Xavier.Leroy@@inria.fr}.

Der schwierige Teil der Portierung auf eine neue Unix-Variante ohne gute
native Thread-Unterstützung ist wahrscheinlich, MIT-pThread zu portieren.
Siehe @file{with-pThread/README} und
@uref{http://www.humanfactor.com/pThread/, POSIX-Thread programmieren}.

Die MySQL-Distribution enthält eine gepatchte Version von Provenzanos
PThread von MIT (siehe
@uref{http://www.mit.edu:8001/people/proven/pThread.html,
MIT-PThread-Website}). Diese kann für einige Betriebssysteme benutzt
werden, die kein POSIX-Thread haben.

Es ist ebenfalls möglich, ein anderes Thread-Paket auf Benutzerebene namens
FSU-PThread zu benutzen (siehe
@uref{http://www.informatik.hu-berlin.de/~mueller/pThread.html,
FSU-PThread-Homepage}). Diese Implementation wird für die SCO-Portierung
benutzt.

In den @file{thr_lock.c}- und @file{thr_alarm.c}-Programmen im
@file{mysys}-Verzeichnis finden Sie einige Tests / Beispiele dieser
Probleme.

Sowohl Server als auch Client benötigen einen funktionierenden C++-Kompiler
(wir benutzen @code{gcc} und haben SparcWorks ausprobiert). Ein anderer
bekanntermaßen funktionierender Compiler ist Irix @code{cc}.

Um nur den Client zu kompilieren, benutzen Sie @code{./configure
--without-server}.

Es gibt momentan keine Unterstützung, um nur den Server zu kompilieren,
noch ist es wahrscheinlich, dass eine solche hinzugefügt wird, falls nicht
jemand einen guten Grund dafür findet.

Wenn Sie irgend welche @file{Makefile} oder das configure-Skript ändern
wollen / müssen, müssen Sie sich Automake und Autoconf holen. Wir haben die
@code{automake-1.2}- und @code{autoconf-2.12}-Distributionen benutzt.

Alle Schritte, die notwendig sind, um alles aus den grundlegendsten Dateien
neu zu machen (make):

@example
/bin/rm */.deps/*.P
/bin/rm -f config.cache
aclocal
autoheader
aclocal
automake
autoconf
./configure --with-debug=full --prefix='ihr_installationsverzeichnis'

# Die oben erzeugten makefiles benötigen GNU-make 3.75 oder neuer.
# (unten gmake genannt)
gmake clean all install init-db
@end example

Wenn Sie bei einer neuen Portierung Probleme bekommen, kann es sein, dass
Sie MySQL etwas debuggen müssen! @xref{Debugging server}.

@strong{HINWEIS:} Bevor Sie mit dem Debuggen von @code{mysqld} anfangen,
bringen Sie sich zuerst die Testprogramme @code{mysys/thr_alarm} und
@code{mysys/thr_lock} zum Laufen. Das stellt sicher, dass Ihre
Thread-Installation zumindest überhaupt eine Chance hat, zu funktionieren!



@menu
* Debugging server::            
* Debugging client::            
* The DBUG package::            
* Locking methods::             
* RTS-threads::                 
* Thread packages::             
@end menu

@node Debugging server, Debugging client, Porting, Porting
@c German node Server debuggen
@appendixsec Einen MySQL-Server debuggen

@cindex Server, debuggen
@cindex debuggen, Server
@cindex Absturz

Wenn Sie Funktionalität benutzen, die in MySQL sehr neu ist, können Sie
versuchen, @code{mysqld} mit der @code{--skip-new}-Option laufen zu lassen
(die alle sehr neue, potenziell unsichere Funktionalität abschaltet) oder
mit @code{--safe-mode}, was viel an Optimierung abschaltet, die
möglicherweise Probleme verursacht. @xref{Crashing}.

Wenn @code{mysqld} nicht starten will, sollten Sie prüfen, ob Sie irgend
welche @code{my.cnf}-Dateien haben, die mit Ihrer Konfiguration in Konflikt
kommen! Sie können Ihre @code{my.cnf}-Argumente mit @code{mysqld
--print-defaults} prüfen und sie vermeiden, indem Sie mit @code{mysqld
--no-defaults ...} starten.

Wenn @code{mysqld} anfängt, Prozessorleistung oder Speicher zu fressen,
oder wenn er ``hängt'', können Sie @code{mysqladmin processlist status}
benutzen, um herauszufinden, ob irgend etwas eine Anfrage ausführt, die
sehr lange dauert. Es ist eine gute Idee, @code{mysqladmin -i10 processlist
status} in irgend einem Fenster laufen zu haben, wenn Sie
Performance-Probleme oder Probleme damit haben, dass sich neue Clients
nicht verbinden können.

Der Befehl @code{mysqladmin debug} dumpt Informationen über Sperren, die in
Gebrauch sind, den benutzten Speicher und den Anfragengebrauch in die
mysql-Log-Datei aus. Das kann helfen, einige Probleme zu lösen. Dieser
Befehl stellt auch nützliche Informationen zur Verfügung, selbst wenn Sie
MySQL nicht zum Debuggen kompiliert haben!

Wenn das Problem darin besteht, dass einige Tabellen langsamer und
langsamer werden, sollten Sie versuchen, die Tabelle mit @code{OPTIMIZE
TABLE} der @code{myisamchk} zu optimieren.
@xref{MySQL Database Administration}. Sie sollten langsame Anfragen
darüber hinaus mit @code{EXPLAIN} überprüfen.

Ebenfalls sollten Sie den Abschnitt über betriebssystemspezifische Dinge in
diesem Handbuch lesen, weil Sie Probleme haben könnten, die einzigartig für
Ihre Umgebung sind. @xref{Operating System Specific Notes}.



@menu
* Compiling for debugging::     
* Making trace files::          
* Using gdb on mysqld::         
* Using stack trace::           
* Using log files::             
* Reproduceable test case::     
@end menu

@node Compiling for debugging, Making trace files, Debugging server, Debugging server
@c German node Zum Debuggen kompilieren
@appendixsubsec MySQL zum Debuggen kompilieren

Wenn Sie sehr spezielle Probleme haben, können Sie immer versuchen, MySQL
zu debuggen. Dafür müssen Sie MySQL mit der @code{--with-debug}- oder der
@code{--with-debug=full}-Option kompilieren. Sie können prüfen, ob MySQL
mit Debuggen kompiliert wurde oder nicht, wenn Sie @code{mysqld --help}
ausführen. Wenn das @code{--debug}-Flag in den Optionen aufgeführt ist,
haben Sie Debuggen eingeschaltet. @code{mysqladmin ver} gibt die
@code{mysqld}-Version in diesem Fall ebenfalls als @code{mysql ... --debug}
aus.

Wenn Sie gcc oder egcs benutzen, ist die empfohlene configure-Zeile:

@example
CC=gcc CFLAGS="-O2" CXX=gcc CXXFLAGS="-O2 -felide-constructors -fno-exceptions -fno-rtti" ./configure --prefix=/usr/local/mysql --with-debug --with-extra-charsets=complex
@end example

Das vermeidet Probleme mit der @code{libstdc++}-Bibliothek und mit
C++-Ausnahmen (viele Compiler haben Probleme mit C++-Ausnahmen in threaded
Code) und kompiliert eine MySQL-Version mit Unterstützung für alle
Zeichensätze.

Wenn Sie einen Speicherüberlauffehler vermuten, können Sie MySQL mit
@code{--with-debug=full} kompilieren, was zusätzlich einen
(@code{SAFEMALLOC})-Prüfer für die Speicherzuweisung installiert. Das
Laufenlassen mit @code{SAFEMALLOC} ist jedoch recht langsam. Wenn Sie daher
Performance-Probleme bekommen, sollten Sie @code{mysqld} mit der
@code{--skip-safemalloc}-Option starten. Das schaltet die
Speicherüberlaufprüfung für jeden Aufruf von @code{malloc} und @code{free}
ab.

Wenn @code{mysqld} nicht mehr abstürzt, wenn Sie ihn mit
@code{--with-debug} kompilieren, haben Sie wahrscheinlich einen
Compiler-Bug oder einen Timing-Bug innerhalb von MySQL gefunden. In diesem
Fall können Sie versuchen, @code{-g} für die @code{CFLAGS}- und
@code{CXXFLAGS}-Variablen oben hinzuzufügen und nicht mehr
@code{--with-debug} zu benutzen. Wenn @code{mysqld} jetzt stirbt, können
Sie wenigstens mit @code{gdb} mit ihm verbinden oder @code{gdb} auf die
Core-Datei benutzen, um herauszufinden, was passiert ist.

Wenn Sie MySQL zum Debuggen konfigurieren, können Sie viele zusätzliche
Sicherheitprüffunktionen hinzufügen, die die Gesundheit von @code{mysqld}
beobachten. Wenn Sie etwas ``Unerwartetes'' finden, wird ein Eintrag nach
@code{stderr} geschrieben, den @code{safe_mysqld} in die Fehler-Log-Datei
leitet! Das heißt auch, dass Sie bei unerwarteten Problemen mit MySQL und
der Benutzung einer Quelldistribution als erstes MySQL zum Debuggen
konfigurieren sollten! (Die zweite Sache wäre natürlich, eine E-Mail an
@email{mysql@@lists.mysql.com} zu schicken und um Hilfe zu bitten. Bitte
benutzen Sie das @code{mysqlbug}-Skript für alle Bug-Berichte oder Fragen
hinsichtlich der MySQL-Version, die Sie benutzen!

In der Windows-MySQL-Distribution wird @code{mysqld.exe} vorgabemäßig mit
Unterstützung für Trace-Dateien kompiliert.


@node Making trace files, Using gdb on mysqld, Compiling for debugging, Debugging server
@c German node Trace-Dateien
@appendixsubsec Trace-Dateien erzeugen

Wenn der @code{mysqld}-Server nicht startet oder wenn Sie den
@code{mysqld}-Server schnell zum Absturz bringen können, können Sie
versuchen, eine Trace-Datei zu erzeugen, um das Problem zu finden.

Hierfür brauchen Sie einen @code{mysqld}, der zum Debuggen kompiliert ist.
Sie können das mit @code{mysqld -V} prüfen. Wenn die Versionsnummer mit
@code{-debug} endet, ist Unterstützung für Trace-Dateien einkompiliert.

Starten Sie den @code{mysqld}-Server mit einem Trace-Log in
@file{/tmp/mysqld.trace} (oder @file{C:\mysqld.trace} unter Windows):

@code{mysqld --debug}

Unter Windows sollten Sie auch den @code{--standalone}-Flag benutzen, um
@code{mysqld} nicht als Systemdienst zu starten.

Machen Sie folgendes in einem DOS-Fenster:

@example
mysqld --debug --standalone
@end example

Danach können Sie das @code{mysql.exe}-Kommandozeilenwerkzeug in einem
zweiten DOS-Fenster benutzen, um das Problem zu reproduzieren. Sie können
den obigen @code{mysqld}-Server mit @code{mysqladmin shutdown} herunter
fahren.

Beachten Sie, dass die Trace-Datei sehr @emph{Groß} wird! Wenn Sie eine
kleinere Trace-Datei haben wollen, können Sie etwa folgendes tun:

@code{mysqld --debug=d,info,error,query,general,where:O,/tmp/mysqld.trace}

Das gibt nur Informationen für die interessantesten Dinge in
@file{/tmp/mysqld.trace} aus.

Wenn Sie hierüber einen Bug-Bericht erstellen, schicken Sie bitte nur die
Zeilen aus der Trace-Datei an die entsprechende Mailing-Liste, in denen
etwas schief zu gehen scheint! Wenn Sie diese Stelle nicht finden können,
können Sie die Trace-Datei per FTP einschicken, zusammen mit einem
kompletten Bug-Bericht, an @uref{ftp://Support.mysql.com/pub/mysql/secret},
so dass ein MySQL-Entwickler sich das ansehen kann.

Die Trace-Datei wird mit dem @strong{DBUG}-Paket von Fred Fish hergestellt.
@xref{The DBUG package}.


@node Using gdb on mysqld, Using stack trace, Making trace files, Debugging server
@c German node gdb auf mysqld benutzen
@appendixsubsec mysqld unter gdb debuggen

@cindex gdb, using

Auf den meisten Systemen können Sie @code{mysqld} von @code{gdb} starten,
um mehr Informationen zu erhalten, wenn @code{mysqld} abstürzt.

Bei einigen älteren @code{gdb}-Versionen unter Linux müssen Sie @code{run
--one-thread} benutzen, um den @code{mysqld}-Thread debuggen zu können. In
diesem Fall können Sie zur gleichen Zeit nur einen Thread aktiv haben.

Wenn Sie @code{mysqld} unter gdb laufen lassen, sollten Sie den Stack-Trace
mit @code{--skip-stack-trace} abschalten, um Segmentation-Fehler innerhalb
gdb abfangen zu können.

Es ist sehr schwierig, MySQL unter @code{gdb} zu debuggen, wenn Sie
permanent viele neue Verbindungen aufbauen, weil @code{gdb} den Speicher
für den alten Thread nicht freigibt. Sie können dieses Problem vermeiden,
indem Sie @code{mysqld} mit @code{-O thread_cache_size=
'maximale_verbindungen +1'} starten. In den meisten Fällen hilft bereits
schon die Benutzung von @code{-O thread_cache_size=5'} recht viel!

Wenn Sie einen Coredump unter Linux erhalten wollen, wenn @code{mysqld} mit
einem SIGSEGV-Signal stirbt, können Sie @code{mysqld} mit der
@code{--core-file}-Option starten. Diese Core-Datei kann benutzt werden, um
eine Zurückverfolgung (Backtrace) zu machen, die Ihnen helfen kann
herauszufinden, warum @code{mysqld} starb:

@example
shell> gdb mysqld core
gdb>   backtrace full
gdb>   exit
@end example

@xref{Crashing}.

Wenn Sie gdb 4.17.x oder höher unter Linux benutzen, sollten Sie eine
@file{.gdb}-Datei mit folgenden Informationen in Ihrem aktuellen
Verzeichnis installieren:

@example
set print sevenbit off
handle SIGUSR1 nostop noprint
handle SIGUSR2 nostop noprint
handle SIGWAITING nostop noprint
handle SIGLWP nostop noprint
handle SIGPIPE nostop
handle SIGALRM nostop
handle SIGHUP nostop
handle SIGTERM nostop noprint
@end example

Wenn Sie Probleme haben, den Thread mit gdb zu debuggen, sollten Sie gdb
5.x herunter laden und diesen statt dessen benutzen. Die neue gdb-Version
hat eine stark verbesserte Thread-Handhabung!

Hier ist ein Beispiel, wie man mysqld debuggt:

@example
shell> gdb /usr/local/libexec/mysqld
gdb> run
...
backtrace full # Tun Sie das, wenn mysqld abstürzt
@end example

Schließen Sie die obige Ausgabe in eine Mail ein, die mit @code{mysqlbug}
erzeugt wurde und schicken Sie sie an @code{mysql@@lists.mysql.com}.

Wenn @code{mysqld} hängen bleibt, können Sie versuchen, einige
Systemwerkzeuge wie @code{strace} oder @code{/usr/proc/bin/pstack} zu
benutzen, um herauszufinden, was @code{mysqld} zum Hängen brachte.

@example
strace /tmp/log libexec/mysqld
@end example

@findex DBI->trace
@findex Trace-DBI-Methode
@tindex DBI_TRACE-Umgebungsvariable
@tindex Umgebungsvariable, DBI_TRACE
Wenn Sie die Perl-@code{DBI}-Schnittstelle benutzen, können Sie
Debug-Informationen anschalten, indem Sie die @code{trace}-Methode benutzen
oder die @code{DBI_TRACE}-Umgebungsvariable setzen.
@xref{Perl DBI Class, , Perl @code{DBI} Class}.


@node Using stack trace, Using log files, Using gdb on mysqld, Debugging server
@c German node Stack-Trace benutzen
@appendixsubsec Einen Stack-Trace benutzen

Auf manchen Betriebssystemen enthält die Fehler-Log-Datei einen
Stack-Trace, wenn @code{mysqld} unerwartet stirbt. Diese können Sie
benutzen, um herauszufinden, wo (und vielleicht warum) @code{mysqld} starb.
@xref{Error log}. Um einen Stack-Trace zu erhalten, sollten Sie
@code{mysqld} NICHT mit der @code{-fomit-frame-pointer}-Option für gcc
kompilieren. @xref{Compiling for debugging}.

Wenn die Fehlerdatei etwas wie folgendes enthält:

@example
mysqld got signal 11;
The manual section 'debugging a MySQL server' tells you how to use a
stack trace and/or the core file to produce a readable backtrace that may
help in finding out why mysqld died
Attemping backtrace. You can use the following information to find out
where mysqld died.  Wenn you see no messages after this, something went
terribly wrong
stack range sanity check, ok, backtrace follows
0x40077552
0x81281a0
0x8128f47
0x8127be0
0x8127995
0x8104947
0x80ff28f
0x810131b
0x80ee4bc
0x80c3c91
0x80c6b43
0x80c1fd9
0x80c1686
@end example

Können Sie herausfinden, wo @code{mysqld} starb, indem Sie folgendes tun:

@enumerate
@item
Kopieren Sie die obigen Zahlen in eine Datei, zum Beispiel
@file{mysqld.stack}.

@item
Machen Sie eine symbolische Datei für den @code{mysqld}-Server:
@example
nm -n libexec/mysqld > /tmp/mysqld.sym
@end example

Beachten Sie, dass viele MySQL-Binärdistributionen die obige Datei namens
@code{mysqld.sym.gz} enthalten. In diesem Fall müssen Sie sie wie folgt
entpacken:
@example
gunzip < bin/mysqld.sym.gz > /tmp/mysqld.sym
@end example

@item
Führen Sie @code{resolve_stack_dump -s /tmp/mysqld.sym -n mysqld.stack}
aus.

Das gibt aus, wo @code{mysqld} starb. Wenn Ihnen das nicht hilft,
herauszufinden, warum @code{mysqld} starb, sollten Sie einen Bug-Bericht
machen und die Ausgabe des obigen Befehls in diesen Bericht einschließen.

Beachten Sie aber, dass es uns in den meisten Fällen nicht weiterhilft, nur
einen Stack-Trace zu haben, um die Ursache des Problems herauszufinden. Um
den Bug feststellen oder einen Workaround zur Verfügung stellen zu können,
müssen wir in den meisten Fällen die Anfrage kennen, die @code{mysqld}
tötete, und am besten einen Testfall, so dass wir das Problem wiederholen
können! @xref{Bug reports}.
@end enumerate


@node Using log files, Reproduceable test case, Using stack trace, Debugging server
@c German node Log-Dateien benutzen
@appendixsubsec Log-Dateien benutzen, um Gründe für Fehler in mysqld zu finden

Beachten Sie, dass Sie vor dem Start von @code{mysqld} mit @code{--log}
alle Ihre Tabellen mit @code{myisamchk} prüfen sollten.
@xref{MySQL Database Administration}.

Wenn @code{mysqld} stirbt oder hängenbleibt, sollten Sie ihn mit
@code{--log} starten. Wenn @code{mysqld} wieder stirbt, können Sie das Ende
der Log-Datei nach der Anfrage durchsuchen, die @code{mysqld} tötete.

Wenn Sie @code{--log} ohne einen Dateinamen verwenden, wird das Log im
Datenbank-Verzeichnis als 'hostname'.log gespeichert. In den meisten Fällen
ist es die letzte Anfrage in der Log-Datei, die @code{mysqld} tötete, aber
das sollten Sie falls möglich sicherstellen, indem Sie @code{mysqld} neu
starten und dieselbe Anfrage mit dem @code{mysql}-Kommandozeilenwerkzeug
wiederholen. Wenn das funktioniert, sollten Sie ebenfalls alle
komplizierten Anfragen testen, die nicht beendet wurden.

Sie können auch den Befehl @code{EXPLAIN} auf alle @code{SELECT}-Statements
ausprobieren, die lange Zeit benötigen, um sicherzustellen, dass
@code{mysqld} Indexe korrekt benutzt. @xref{EXPLAIN, , @code{EXPLAIN}}.

Sie finden Anfragen, die zur Ausführung lange Zeit benötigen, indem Sie
@code{mysqld} mit @code{--log-slow-queries} starten.
@xref{Slow query log}.

Wenn Sie den Text @code{mysqld restarted} in der Fehler-Log-Datei-Datei
(normalerweise namens @file{hostname.err}) finden, haben Sie wahrscheinlich
eine Anfrage gefunden, die @code{mysqld} zum Absturz brachte. Wenn das
passiert, sollten Sie alle Ihre Tabellen mit @code{myisamchk} prüfen
(@pxref{MySQL Database Administration}) und die Anfragen in den
MySQL-Log-Dateien untersuchen, um herauszufinden, ob eine nicht
funktioniert. Wenn Sie eine solche Anfrage finden, versuchen Sie zunächst,
auf die neueste MySQL-Version zu aktualisieren. Wenn das nicht hilft und Sie
nichts im @code{mysql}-Mailarchiv finden können, sollten Sie den Bug an
@email{mysql@@lists.mysql.com} berichten. Links zu Mailarchiven finden Sie
online auf der @uref{http://www.mysql.com/documentation/,
MySQL-Dokumentationsseite}.

Wenn Sie @code{mysqld} mit @code{--with-myisam-recover} gestartet haben,
prüft MySQL automatisch @code{MyISAM}-Tabellen und versucht sie zu
reparieren, wenn sie als 'nicht korrekt geschlossen' oder 'beschädigt'
gekennzeichnet sind. Wenn das passiert, schreibt MySQL einen Eintrag in die
@code{hostname.err}-Datei @code{'Warning: Checking table ...'}, der von
@code{Warning: Repairing table} gefolgt wird, wenn die Tabelle repariert
werden muss. Wenn Sie viele solcher Fehler erhalten, ohne dass
@code{mysqld} direkt davor unerwartet gestorben ist, stimmt etwas nicht und
muss weiter untersucht werden. @xref{Command-line options}.

Natürlich ist es kein gutes Zeichen, wenn @code{mysqld} unerwartet stirbt,
doch in diesem Fall sollte man nicht die @code{Checking table...}-Meldungen
untersuchen, sondern statt dessen versuchen herauszufinden, warum
@code{mysqld} starb.


@node Reproduceable test case,  , Using log files, Debugging server
@c German node Reproduzierbarer Testfall
@appendixsubsec Einen Testfall herstellen, wenn Sie Tabellenbeschädigung feststellen

Wenn Sie beschädigte Tabellen erhalten oder wenn @code{mysqld} immer nach
irgend einem Aktualisierungsbefehl fehlschlägt, können Sie mit folgendem
überprüfen, ob der Bug reproduzierbar ist:

@itemize @bullet
@item
Fahren Sie den MySQL-Daemon herunter (mit @code{mysqladmin shutdown}).
@item
Machen Sie eine Datensicherung der Tabellen (um dem sehr unwahrscheinlichen
Fall vorzubeugen, dass die Reparatur etwas Schlechtes macht).
@item
Prüfen Sie alle Tabellen mit @code{myisamchk -s Datenbank/*.MYI}.
Reparieren Sie jegliche beschädigten Tabellen mit @code{myisamchk -r
datenbank/tabelle.MYI}.
@item
Machen Sie eine Datensicherung der Tabellen.
@item
Entfernen (oder verschieben) Sie jegliche alten Log-Dateien aus dem
MySQL-Daten-Verzeichnis, wenn Sie mehr Platz brauchen.
@item
Starten Sie @code{mysqld} mit @code{--log-binary}. @xref{Binary log}.
Wenn Sie eine Anfrage finden wollen, die @code{mysqld} zum Absturz brachte,
sollten Sie @code{--log --log-binary} benutzen.
@item
Wenn Sie eine beschädigte Tabelle erhalten, halten Sie @code{mysqld} an.
@item
Stellen Sie die Datensicherung wieder her.
@item
Starten Sie den @code{mysqld}-Server neu, @strong{ohne}
@code{--log-binary}.
@item
Führen Sie die Befehle mit @code{mysqlbinlog update-log-file | mysql}
erneut aus. Die Update-Log-Datei wird im MySQL-Datenbank-Verzeichnis unter
dem Namen @code{hostname-bin.#} gespeichert.
@item
Wenn die Tabellen wieder beschädigt werden oder Sie @code{mysqld} wieder
dazu bringen können zu sterben, haben Sie einen reproduzierbaren Bug
gefunden, der sich leicht beheben lassen sollte! Schicken Sie die Tabellen
und die Binär-Log-Datei an @uref{ftp://support.mysql.com/pub/mysql/secret}
und schicken Sie eine E-Mail an @email{bugs@@lists.mysql.com} oder (wenn
Sie ein Support-Kunde sind) an @email{Support@@mysql.com}, und das
MySQL-Team wird den Bug so schnell wie möglich beheben.
@end itemize

Sie können auch das Skript @code{mysql_find_rows} benutzen, um einfach
einige der Aktualisierungs-Statements auszuführen, wenn Sie das Problem
eingrenzen wollen.


@node Debugging client, The DBUG package, Debugging server, Porting
@c German node Clients debuggen
@appendixsec Einen MySQL-Client debuggen

@cindex debuggen, Client
@cindex Clients, debuggen

Um einen MySQL-Client mit dem integrierten Debug-Paket debuggen zu können,
sollten Sie MySQL mit @code{--with-debug} oder @code{--with-debug=full}
kompilieren. @xref{configure options}.

@tindex MYSQL_DEBUG-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_DEBUG
Bevor Sie einen Client laufen lassen, sollten Sie die
@code{MYSQL_DEBUG}-Umgebungsvariable setzen:

@example
shell> MYSQL_DEBUG=d:t:O,/tmp/client.trace
shell> export MYSQL_DEBUG
@end example

Das bringt Clients dazu, eine Trace-Datei in @file{/tmp/client.trace} zu
erzeugen.

Wenn Sie Probleme mit Ihrem eigenen Client-Code haben, sollten Sie
versuchen, sich mit dem Server zu verbinden und Ihre Anfragen mit einem
Client laufen zu lassen, der bekanntermaßen funktioniert. Lassen Sie dabei
@code{mysql} im Debug-Modus laufen (unter der Annahme, dass Sie MySQL mit
angeschaltetem Debuggen kompiliert haben):

@example
shell> mysql --debug=d:t:O,/tmp/client.trace
@end example

Das stellt nützliche Informationen für den Fall bereit, dass Sie einen
Bug-Bericht schicken. @xref{Bug reports}.

Wenn Ihr Client bei irgend einem 'zulässigen' Sperr-Code abstürzt, sollten
Sie sicherstellen, dass Ihre @file{mysql.h}-Include-Datei mit Ihrer
MySQL-Bibliotheksdatei zusammenpasst. Es ist ein häufiger Fehler, eine alte
@file{mysql.h}-Datei aus einer alten MySQL-Installation mit einer neuen
MySQL-Bibliothek zu benutzen.


@node The DBUG package, Locking methods, Debugging client, Porting
@c German node Das DBUG-Paket
@appendixsec Das DBUG-Paket

@cindex DBUG-Paket

Der MySQL-Server und die meisten MySQL-Clients werden mit dem DBUG-Paket
kompiliert, das ursprünglich von Fred Fish stammt. Wenn man MySQL zum
Debuggen kompiliert hat, ermöglicht es dieses Paket, eine Trace-Datei davon
zu erhalten, was das Programm debuggt. @xref{Making trace files}.

Man benutzt das Debug-Paket durch Aufruf des Programms mit der
@code{--debug="..."}- oder der @code{-#...}-Option.

Die meisten MySQL-Programme haben eine vorgabemäßige Debug-Zeichenkette,
die benutzt wird, wenn Sie keine Option für @code{--debug} angeben. Die
vorgabemäßige Trace-Datei ist üblicherweise
@code{/tmp/programm_name.trace} unter Unix und @code{\programm_name.trace}
unter Windows.

Die Debug-Steuerungs-Zeichenkette ist eine Folge durch Doppelpunkte
getrennter Felder, wie folgt:

@example
<feld_1>:<feld_2>:...:<feld_N>
@end example

Jedes Feld besteht aus einem zwingend erforderlichen Flag-Zeichen, gefolgt
durch ein optionales Komma (",") und eine durch Kommas getrennte Auflistung
von Modifikatoren:

@example
flag[,modifikator,modifikator,...,modifikator]
@end example

Aktuell werden folgende Flag-Zeichen erkannt:

@multitable @columnfractions .1 .9
@item d
 @tab Ausgabe von DBUG_<N>-Makros des aktuellen Status ermöglichen.
Gegebenenfalls gefolgt von einer Auflistung von Schlüsselwörtern, die
Ausgaben nur für die DBUG-Makros mit diesem Schlüsselwort auswählt. Eine
leere  Auflistung von Schlüsselwörtern bedeutet Ausgabe für alle Makros.
@item D
 @tab Nach jeder Debugger-Ausgabezeile verzögern. Das Argument ist die
Anzahl von Zehntelsekunden der Verzögerung, abhängig von den Fähigkeiten
der Maschine. @code{-#D,20} bedeutet als eine Verzögerung von 2 Sekunden.
@item f	
 @tab Debuggen und / oder Tracen und Profilen auf die in der Auflistung
genannten Funktionen beschränken. Beachten Sie, dass eine leere Liste alle
Funktionen abschaltet. Die entsprechenden "d"- oder "t"-Flags müssen immer
noch angegeben werden; dieser Flag beschränkt nur ihre Aktionen, wenn Sie
angeschaltet sind.
@item F	
 @tab Den Quell-Dateinamen für jede Zeile der Debug- oder Trace-Ausgabe
festlegen.
@item i	
 @tab Den Prozess mit der PID- oder Thread-Kennung für jede Ziele der
Debug- oder Trace-Ausgabe festlegen.
@item g	@tab Profiling anschalten. Es wird eine Datei namens 'dbugmon.out'
erzeugt, die Informationen enthält, die benutzt werden können, um das
Programm zu profilen. Wir gegebenenfalls von einer Auflistung von
Schlüsselwörter gefolgt, die Profiling nur für die Funktionen in dieser
Liste auswählen. Eine leere Liste bedeutet, dass alle Funktionen in
Betracht gezogen werden.
@item L	
 @tab Die Quell-Datei-Zeilennummer für jede Zeile der Debug- oder
Trace-Ausgabe festlegen.
@item n	
 @tab Die aktuelle Funktionsverschachtelungstiefe für jede Zeile der Debug-
oder Trace-Ausgabe ausgeben.
@item N 
 @tab Jede Zeile der dbug-Ausgabe nummerieren.
@item o 
 @tab Die Debugger-Ausgabe in die angegebene Datei umlenken. Die
vorgabemäßige Ausgabe ist stderr.
@item O 
 @tab Wie @code{O}, aber die Datei wird nach jedem Schreiben auf die Platte
zurückgeschrieben (flush). Wenn nötig, wird die Datei geschlossen und
wieder geöffnet.
@item p 
 @tab Debugger-Aktionen auf die angegebenen Prozesse beschränken. Ein
Prozess muss mit dem DBUG_PROCESS-Makro gekennzeichnet sein und mit einer
der Aktionen in der Liste übereinstimmen, damit Debugger-Aktionen
durchgeführt werden.
@item P 
 @tab Den aktuellen Prozessnamen für jede Zeile der Debug- oder
Trace-Ausgabe ausgeben.
@item r 
 @tab Wenn ein neuer Zustand gepusht wird, nicht die
Funktionsverschachtelungsebene des alten Zustands übernehmen (erben).
Nützlich, wenn die Ausgabe am linken Rand anfangen soll.
@item S 
 @tab Funktion _sanity(_datei_,_zeile_) bei jeder debuggten Funktion
ausführen, bis _sanity() etwas anderes als 0 zurückgibt. (Wird meist
zusammen mit safemalloc benutzt, um Speicherlecks zu finden.)
@item t 
 @tab Trace-Zeile für Funktionsaufrufen / Funktionsende anschalten. Wird
gegebenenfalls gefolgt von einer Liste (die nur einen Modifikator enthält), in
der numerisch eine maximale Trace-Ebene angegeben wird, nach der keine
Ausgaben mehr erfolgen, weder für Debuggen noch für das Tracen von Makros. Die
Vorgabe ist eine Kompilierzeit-Option.
@end multitable

Einige Beispiele von Debug-Steuerungs-Zeichenketten, die auf einer
Shell-Kommandozeile erscheinen können (das "-#" wird typischerweise
benutzt, um eine Steuerungs-Zeichenkette für ein Applikationsprogramm
einzuführen):

@example
-#d:t
-#d:f,main,subr1:F:L:t,20
-#d,input,output,files:n
-#d:t:i:O,\\mysqld.trace
@end example

In MySQL werden gebräuchlicherweise (mit der @code{d}-Option) folgende Tags
ausgegeben: @code{enter}, @code{exit}, @code{error}, @code{warning},
@code{info} und @code{loop}.


@node Locking methods, RTS-threads, The DBUG package, Porting
@c German node Sperrmethoden
@appendixsec Sperrmethoden

@cindex Sperrmethoden
@cindex Methoden, Sperr-

Momentan unterstützt MySQL Tabellensperren nur für @code{ISAM}- /
@code{MyISAM}- und @code{HEAP}-Tabellen und Sperren auf Seitenebene nur für
@code{BDB}-Tabellen. @xref{Internal locking}. Bei @code{MyISAM}-Tabellen
können Sie @code{INSERT} und @code{SELECT} ohne Sperren frei vermischen.
(@code{Versionierung}).

Ab Version 3.23.33 können Sie die Tabellensperr-Konkurrenz auf Ihrem System
durch Prüfen der @code{Table_locks_waited}- und
@code{Table_locks_immediate}-Umgebungsvariablen analysieren.

Einige Datenbankbenutzer behaupten, dass MySQL keine große Anzahl
gleichzeitiger Benutzer unterstützen kann, weil es kein Sperren auf
Zeilenebene hat. Das mag bei einigen speziellen Applikationen zutreffen,
aber nicht allgemein. Wie immer hängt das völlig davon ab, was Ihre
Applikation macht, und davon, wie das Zugriffs-/Aktualisierungs-Muster der
Daten aussieht.

Vorteile für Zeilensperren:

@itemize @bullet
@item
Weniger Sperrkonflikte beim Zugriff auf unterschiedliche Zeilen in vielen
Threads.
@item
Weniger Änderungen bei Rollbacks.
@item
Macht es möglich, eine einzelne Zeile lange zu sperren.
@end itemize

Nachteile:

@itemize @bullet
@item
Benötigt mehr Speicher als Sperren auf Seiten- oder Tabellenebene.
@item
Ist langsamer als Sperren auf Seiten- oder Tabellenebene, wenn es einen
großen Teil der Tabelle betrifft, weil man viel mehr Sperren durchführen
muss.
@item
Ist definitiv viel schlechter als andere Sperren, wenn Sie oft @code{GROUP
BY} auf einen großen Teil der Daten ausführen oder wenn man die gesamte
Tabelle oft scannen muss.
@item
Bei Sperren auf höherer Ebene kann man einfacher Sperren unterschiedlichen
Typs unterstützen, um die Applikation zu optimieren, weil der
Sperr-Overhead sich weniger als bei Sperren auf Zeilenebene bemerkbar
macht.
@end itemize

Tabellensperren sind Seiten- oder Zeilensperren in folgenden Fällen
überlegen:

@itemize @bullet
@item
Wenn man meist liest.
@item
Wenn Lese- und Aktualisierungsoperationen auf strengen Schlüsseln erfolgen.
Das ist dann der Fall, wenn man eine Zeile aktualisiert oder löscht, die
mit einem Schlüssel-Lesen geholt werden kann:
@example
UPDATE tabelle SET spalte=wert WHERE eindeutige_schluessel_nummer
DELETE FROM tabelle WHERE eindeutiger_schluessel=#
@end example
@item
@code{SELECT} in Kombination mit @code{INSERT} (und sehr wenigen
@code{UPDATE}'s und @code{DELETE}'s).
@item
Viele Scans / @code{GROUP BY} auf die gesamte Tabelle ohne irgend welche
Schreibvorgänge.
@end itemize

Andere Optionen als Sperren auf Zeilen- / Seiten-Ebene:

Versionierung (wie die, die wir bei MySQL für gleichzeitige Einfügevorgänge
nutzen), bei der man gleichzeitig einen Schreibvorgang haben kann, während
viele Lesevorgänge stattfinden. Das heißt, dass die Datenbank / Tabelle
verschiedene Sichten der Daten unterstützt, abhängig davon, wann man
anfing, darauf zuzugreifen. Andere Namen hierfür sind Zeitreisen, Kopieren
beim Schreiben (Copy on Write) oder Kopieren bei Bedarf (Copy on Demand).

Kopieren bei Bedarf ist in vielen Fällen viel besser als Sperren auf
Seiten- oder Zeilenebene. Im schlimmsten Fall wird jedoch viel mehr
Speicher verbraucht als bei der Benutzung normaler Sperren.

Anstelle von Zeilen-Sperren kann man Sperren auf Applikationsebene
benutzen (wie get_lock/release_lock in MySQL). Das funktioniert natürlich
nur bei 'wohl erzogenen' Applikationen.

In vielen Fällen kann man auf fortgeschrittene Art raten, welcher Sperrtyp
der beste für die Applikation ist, aber allgemein ist es sehr schwer zu
sagen, dass ein bestimmter Sperrtyp besser ist als ein anderer. Alles hängt
von der Applikation ab, und verschiedene Teile der Applikation können nach
unterschiedlichen Sperrtypen verlangen.

Hier sind einige Tipps zu Sperren in MySQL:

Bei Web-Applikation führen die meisten Applikationen viele SELECTs aus,
sehr wenige DELETEs, UPDATEs hauptsächlich auf Schlüssel und INSERTs in
einigen bestimmten Tabellen. Die grundlegende Einrichtung von MySQL ist
hierfür BESTENS optimiert.

Gleichzeitige Benutzer sind kein Problem, solange man UPDATEs und SELECTs
nicht vermischt, die beide gleichzeitig viele Zeilen in derselben Tabelle
untersuchen müssen.

Wenn man INSERTs und DELETEs auf dieselbe Tabelle mischt, kann @code{INSERT
DELAYED} eine große Hilfe sein.

Man kann auch @code{LOCK TABLES} benutzen, um Dinge zu beschleunigen (viele
UPDATEs innerhalb einer einzelnen Sperre sind viel schneller als UPDATEs
ohne Sperren). Daten in unterschiedliche Tabellen aufteilen hilft hierbei
auch.

Wenn Sie Geschwindigkeitsprobleme mit den Tabellensperren in MySQL
bekommen, können Sie diese eventuell dadurch lösen, dass Sie Ihre Tabellen
in @code{BDB}-Tabellen umwandeln.
@xref{BDB}.

Der Optimierungsabschnitt dieses Handbuchs behandelt viele verschiedene
Aspekte dessen, wie man seine Applikationen optimieren kann. @xref{Tips}.


@node RTS-threads, Thread packages, Locking methods, Porting
@c German node RTS-Thread
@appendixsec Anmerkungen zu RTS-Thread

@cindex RTS-Thread
@cindex Thread, RTS

Ich habe versucht, die RTS-Thread-Pakete bei MySQL zu benutzen, bin aber
über folgende Probleme gestolpert:

Sie benutzen die alte Version vieler POSIX-Aufrufe und es ist sehr mühsam,
Wrapper für alle Funktionen zu schreiben. Ich neige dazu zu denken, dass es
leichter ist, die Thread-Bibliotheken auf die neueste POSIX-Spezifikation
zu ändern.

Einige Wrapper sind bereits geschrieben. Siehe @file{mysys/my_pThread.c}
wegen weiterer Informationen.

Zumindest folgendes sollte geändert werden:

@code{pthread_get_specific} sollte ein Argument benutzen.
@code{sigwait} sollte zwei Argumente entgegennehmen.
Viele Funktionen (zumindest @code{pthread_cond_wait} und
@code{pthread_cond_timedwait}) sollten bei einem Fehler den Fehler-Code
zurückgeben. Momentan geben sie -1 zurück und setzen @code{errno}.

Ein weiteres Problem ist, dass Threads auf Benutzerebene das
@code{ALRM}-Signal benutzen und dass dieses viele Funktionen abbricht
(@code{read}, @code{write}, @code{open}, ...). MySQL sollte versuchen, nach
der Unterbrechung all dieser Funktionen weiterzumachen, aber das ist nicht
einfach zu verifizieren.

Das größte ungelöste Problem ist folgendes:

Um Alarme auf Thread-Ebene zu erhalten, änderte ich
@file{mysys/thr_alarm.c} in der Art, dass es zwischen Alarmen wartet, mit
@code{pthread_cond_timedwait()}, aber das bricht mit Fehler @code{EINTR}
ab. Ich versuchte, die Thread-Bibliothek zu debuggen, um den Grund
herauszufinden, konnte aber keine einfache Lösung finden.

Wenn jemand MySQL mit RTS-Thread ausprobieren möchte, schlage ich folgendes
vor:

@itemize @bullet
@item
Funktionen, die MySQL benutzt, von der Thread-Bibliothek zu POSIX ändern.
Das sollte nicht lange dauern.
@item
Alle Bibliotheken mit @code{-DHAVE_rts_thread} kompilieren.
@item
@code{thr_alarm} kompilieren.
@item
Wenn es kleine Unterschiede in der Implementation gibt, können diese
behoben werden, indem man @file{my_pThread.h} und @file{my_pThread.c}
ändert.
@item
@code{thr_alarm} laufen lassen. Wenn es ohne irgend welche ``warning''-,
``error''- oder ``aborted''-Meldungen läuft, sind Sie auf dem richtigen
Weg. Hier ist ein erfolgreiches Laufenlassen unter Solaris:
@example
Main Thread: 1
Thread 0 (5) started
Thread: 5  Waiting
process_alarm
Thread 1 (6) started
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 1 (1) sec
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 2 (2) sec
Thread: 6  Simulation of no alarm needed
Thread: 6  Slept for 0 (3) sec
Thread: 6  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 4 (4) sec
Thread: 6  Waiting
process_alarm
thread_alarm
Thread: 5  Slept for 10 (10) sec
Thread: 5  Waiting
process_alarm
process_alarm
thread_alarm
Thread: 6  Slept for 5 (5) sec
Thread: 6  Waiting
process_alarm
process_alarm

...
thread_alarm
Thread: 5  Slept for 0 (1) sec
end
@end example
@end itemize


@node Thread packages,  , RTS-threads, Porting
@c German node Thread-Pakete
@appendixsec Unterschiede zwischen verschiedenen Thread-Paketen

@cindex Thread-Pakete, Unterschiede

MySQL ist sehr abhängig vom verwendeten Thread-Paket. Wenn Sie daher eine
gute Plattform für MySQL auswählen, ist das Thread-Paket sehr wichtig.

Es gibt mindestens drei Typen von Thread-Paketen:

@itemize @bullet
@item
Benutzer-Thread in einem einzelnen Prozess. Das Thread-Umschalten wird mit
Alarmen gemacht und die Thread-Bibliothek verwaltet alle nicht
Thread-sicheren Funktionen mit Sperren. Lese-, Schreib- und
Auswahl-Operationen werden üblicherweise mit einer Thread-spezifischen
Auswahl verwaltet, die auf einen anderen Thread umschaltet, wenn der
laufende Thread auf Daten warten muss. 
Wenn die Benutzer-Thread-Pakete in die Standard-Bibliotheken integriert
sind (FreeBSD- und BSDI-Thread), erfordert das Thread-Paket weniger
Overhead als Thread-Pakete, die alle unsicheren Aufrufen mappen müssen
(MIT-pThread, FSU-PThread und RTS-Thread). In einigen Umgebungen
(beispielsweise SCO) sind alle Systemaufrufe Thread-sicher, weshalb das
Mapping sehr leicht durchgeführt werden kann (FSU-PThread unter SCO).
Nachteil: Alle gemappten Aufrufe benötigen etwas Zeit und es ist sehr
verzwickt, alle Situationen handhaben zu können. Üblicherweise gibt es auch
einige Systemaufrufe, die vom Thread-Paket nicht gehandhabt werden (wie
MIT-pThread und Sockets). Thread-Scheduling ist nicht immer optimal.
@item
Benutzer-Thread in separaten Prozessen. Das Thread-Umschalten wird vom
Kernel durchgeführt und alle Daten werden zwischen den Threads geteilt. Das
Thread-Paket verwaltet die Standard-Thread-Aufrufe, so dass diese Daten
zwischen Threads teilen können. LinuxThread benutzt diese Methode.
Nachteil: viele Prozesse. Die Erzeugung von Threads ist langsam. Wenn ein
Thread stirbt, bleiben die übrigen üblicherweise hängen, und Sie müssen
alle töten, bevor Sie neu starten können. Man kann sagen, dass die
Thread-Umschaltung ziemlich viel kostet.
@item
Kernel-Thread. Das Thread-Umschalten wird von der Thread-Bibliothek oder
dem Kernel durchgeführt und ist sehr schnell. Alles wird in einem Prozess
gemacht, aber auch manchen Systemen zeigt @code{ps} die verschiedenen
Threads. Wenn ein Thread abbricht, bricht der gesamte Prozess ab. Die
meisten Systemaufrufe sind Thread-sicher und sollten sehr wenig Overhead
beanspruchen. Solaris, HP-UX, AIX und OSF1 haben Kernel-Thread.
@end itemize

Auf manchen Systemen wird Kernel-Thread gehandhabt, indem
Benutzerebenen-Thread in die Systembibliotheken integriert wird. In solchen
Fällen kann das Umschalten nur von der Thread-Bibliothek durchgeführt
werden und der Kernel ist sich nicht wirklich ``der Threads bewusst''.




@node Environment variables, Regexp, Porting, Top
@c German node Umgebungsvariablen
@appendix Umgebungsvariablen

@cindex Umgebungsvariablen, Auflistung

Hier ist eine Auflistung aller Umgebungsvariablen, die direkt oder indirekt
von MySQL benutzt werden. Die meisten von ihnen finden sich auch an anderen
Stellen dieses Handbuchs.

Beachten Sie, dass jegliche Optionen auf der Kommandozeile vorrangig vor
Werten, die in Konfigurationsdateien und Umgebungsvariablen angegeben sind,
und Werte in Konfigurationsdateien vorrangig vor Werten in
Umgebungsvariablen sind.

In vielen Fällen ist es vorzuziehen, eine configure-Datei anstelle von
Umgebungsvariablen zu verwenden, um das Verhalten von MySQL zu
beeinflussen. @xref{Option files}.

@tindex CCX-Umgebungsvariable
@tindex Umgebungsvariable, CCX
@tindex CC-Umgebungsvariable
@tindex Umgebungsvariable, CC
@tindex CFLAGS-Umgebungsvariable
@tindex Umgebungsvariable, CFLAGS
@tindex CXXFLAGS-Umgebungsvariable
@tindex Umgebungsvariable, CXXFLAGS
@tindex DBI_USER-Umgebungsvariable
@tindex Umgebungsvariable, DBI_USER
@tindex DBI_TRACE-Umgebungsvariable
@tindex Umgebungsvariable, DBI_TRACE
@tindex HOME-Umgebungsvariable
@tindex Umgebungsvariable, HOME
@tindex LD_RUN_PATH-Umgebungsvariable
@tindex Umgebungsvariable, LD_RUN_PATH
@tindex MYSQL_DEBUG-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_DEBUG
@tindex MYSQL_HISTFILE-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_HISTFILE
@tindex MYSQL_HOST-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_HOST
@tindex MYSQL_PWD-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_PWD
@tindex MYSQL_TCP_PORT-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_TCP_PORT
@tindex MYSQL_UNIX_PORT-Umgebungsvariable
@tindex Umgebungsvariable, MYSQL_UNIX_PORT
@tindex PATH-Umgebungsvariable
@tindex Umgebungsvariable, PATH
@tindex TMPDIR-Umgebungsvariable
@tindex Umgebungsvariable, TMPDIR
@tindex TZ-Umgebungsvariable
@tindex Umgebungsvariable, TZ
@tindex UMASK_DIR-Umgebungsvariable
@tindex Umgebungsvariable, UMASK_DIR
@tindex UMASK-Umgebungsvariable
@tindex Umgebungsvariable, UMASK
@tindex USER-Umgebungsvariable
@tindex Umgebungsvariable, USER

@multitable @columnfractions .2 .8
@item @code{CCX} @tab Setzen Sie diese für Ihren C++-Kompiler, wenn Sie
configure laufen lassen.
@item @code{CC}  @tab Setzen Sie diese für Ihren C-Kompiler, wenn Sie
configure laufen lassen.
@item @code{CFLAGS} @tab Flags für Ihren C-Kompiler, wenn Sie
configure laufen lassen.
@item @code{CXXFLAGS} @tab Flags für Ihren C++-Kompiler wenn Sie
configure laufen lassen.
@item @code{DBI_USER} @tab Der vorgabemäßige Benutzername für Perl-DBI.
@item @code{DBI_TRACE} @tab Beim Tracen in Perl-DBI benutzt.
@item @code{HOME} @tab Der vorgabemäßige Pfad für die
@code{mysql}-History-Datei ist @file{$HOME/.mysql_history}.
@item @code{LD_RUN_PATH} @tab Wird benutzt um anzugeben, wo Ihr
@code{libmysqlclient.so} ist.
@item @code{MYSQL_DEBUG} @tab Debug-Trace-Optionen beim Debuggen.
@item @code{MYSQL_HISTFILE} @tab Der Pfad zur @code{mysql}-History-Datei.
@item @code{MYSQL_HOST} @tab Vorgabemäßiger Hostname, der von der
@code{mysql}-Befehlszeilenaufforderung benutzt wird.
@item @code{MYSQL_PWD} @tab Das vorgabemäßige Passwort bei der Verbindung
mit @code{mysqld}. Beachten Sie, dass die Benutzung dieser
Umgebungsvariablen unsicher ist!
@item @code{MYSQL_TCP_PORT} @tab Der vorgabemäßige TCP/IP-Port.
@item @code{MYSQL_UNIX_PORT} @tab Der vorgabemäßige Socket; benutzt für
Verbindungen nach @code{localhost}.
@item @code{PATH} @tab Wird von der Shell benutzt, um die MySQL-Programme
zu finden.
@item @code{TMPDIR} @tab Das Verzeichnis, in dem temporäre Tabellen /
Dateien erzeugt werden.
@item @code{TZ} @tab Diese Variable sollte auf Ihre lokale Zeitzone gesetzt
sein. @xref{Timezone problems}.
@item @code{UMASK_DIR} @tab Die Erzeugungsmaske (Creation Mask) des
Benutzer-Verzeichnisses, wenn Verzeichnisse angelegt werden. Beachten Sie,
dass diese mit @code{UMASK} mit einem logischen UND verknüpft wird!
@item @code{UMASK} @tab Die Erzeugungsmaske (Creation Mask) bei der
Erzeugung von Dateien.
@item @code{USER} @tab Der vorgabemäßige Benutzer unter Windows, der beim
Verbinden mit @code{mysqld} benutzt wird.
@end multitable




@node Regexp, GPL license, Environment variables, Top
@c German node Reguläre Ausdrücke
@appendix Beschreibung der MySQL-Syntax für reguläre Ausdrücke

@cindex regex
@cindex Syntax regulärer Ausdrücke, Beschreibung
@cindex Syntax, reguläre Ausdrücke

Ein regulärer Ausdruck (regex) ist eine mächtige Möglichkeit, eine komplexe
Suche zu formulieren.

MySQL benutzt Henry Spencers Implementation regulärer Ausdrücke, die
anstrebt, POSIX-1003.2-konform zu sein. MySQL benutzt die erweiterte
Version.

Die vorliegende vereinfachte Referenz überspringt die Details. Um genauere
Informationen zu erhalten, sehen Sie sich Henry Spencers
@code{regex(7)}-Handbuchseite an, die in der Quelldistribution enthalten
ist. @xref{Credits}.

Ein regulärer Ausdruck beschreibt einen Satz von Zeichenketten. Der
einfachste regexp ist einer, der keine Sonderzeichen enthält. Der regexp
@code{hello} beispielsweise stimmt mit @code{hello} und sonst nichts
überein.

Nicht triviale reguläre Ausdrücke benutzen bestimmte spezielle Konstrukte,
so dass sie mit mehr als einer Zeichenkette übereinstimmen können. Der
regexp @code{hallo|stefan} beispielsweise stimmt entweder mit der
Zeichenkette @code{hallo} oder der Zeichenkette @code{stefan} überein.

Um ein komplexeres Beispiel zu geben, stimmt der regexp @code{B[an]*s} mit
jeder der Zeichenketten @code{Bananas}, @code{Baaaaas}, @code{Bs} und jeder
anderen Zeichenkette überein, die mit einem @code{B} anfängt, mit einem
@code{s} aufhört und jede beliebige Anzahl von @code{a}- oder
@code{n}-Zeichen dazwischen enthält.

Ein regulärer Ausdruck kann jedes der folgenden Sonderzeichen bzw.
Konstrukte benutzen (0 = keine Übereinstimmung):
@table @code
@item ^
Stimmt mit dem Anfang einer Zeichenkette überein.
@example
mysql> select "fo\nfo" REGEXP "^fo$";           -> 0
mysql> select "fofo" REGEXP "^fo";              -> 1
@end example
@item $
Stimmt mit dem Ende einer Zeichenkette überein.
@example
mysql> select "fo\no" REGEXP "^fo\no$";         -> 1
mysql> select "fo\no" REGEXP "^fo$";            -> 0
@end example
@item .
Stimmt mit jedem Zeichen überein (inklusive neue Zeile).
@example
mysql> select "fofo" REGEXP "^f.*";             -> 1
mysql> select "fo\nfo" REGEXP "^f.*";           -> 1
@end example
@item a*
Stimmt mit jeder Folge von 0 oder mehr @code{a}-Zeichen überein.
@example
mysql> select "Ban" REGEXP "^Ba*n";             -> 1
mysql> select "Baaan" REGEXP "^Ba*n";           -> 1
mysql> select "Bn" REGEXP "^Ba*n";              -> 1
@end example
@item a+
Stimmt mit jeder Folge von einem oder mehr @code{a}-Zeichen überein.
@example
mysql> select "Ban" REGEXP "^Ba+n";             -> 1
mysql> select "Bn" REGEXP "^Ba+n";              -> 0
@end example
@item a?
Stimmt mit 0 oder einem @code{a}-Zeichen überein.
@example
mysql> select "Bn" REGEXP "^Ba?n";              -> 1
mysql> select "Ban" REGEXP "^Ba?n";             -> 1
mysql> select "Baan" REGEXP "^Ba?n";            -> 0
@end example
@item de|abc
Stimmt mit den Zeichenfolgen @code{de} oder @code{abc} überein.
@example
mysql> select "pi" REGEXP "pi|apa";             -> 1
mysql> select "axe" REGEXP "pi|apa";            -> 0
mysql> select "apa" REGEXP "pi|apa";            -> 1
mysql> select "apa" REGEXP "^(pi|apa)$";        -> 1
mysql> select "pi" REGEXP "^(pi|apa)$";         -> 1
mysql> select "pix" REGEXP "^(pi|apa)$";        -> 0
@end example
@item (abc)*
Stimmt mit 0 oder mehr Instanzen der Folge @code{abc} überein.
@example
mysql> select "pi" REGEXP "^(pi)*$";            -> 1
mysql> select "pip" REGEXP "^(pi)*$";           -> 0
mysql> select "pipi" REGEXP "^(pi)*$";          -> 1
@end example
@item @{1@}
@itemx @{2,3@}
Es gibt eine allgemeinere Schreibweise für regexps, die mit vielen
Vorkommen des vorherigen Atoms übereinstimmen.
@table @code
@item a*
Kann als @code{a@{0,@}} geschrieben werden.
@item a+
Kann als @code{a@{1,@}} geschrieben werden.
@item a?
Kann als @code{a@{0,1@}} geschrieben werden.
@end table

Um genauer zu sein, stimmt ein Atom, gefolgt von einer Begrenzung, die eine
Ganzzahl @code{i} und keine Kommas enthält, mit einer Folge von genau
@code{i} Übereinstimmungen des Atoms überein. Ein Atom gefolgt von einer
Begrenzung, die eine Ganzzahl @code{i} und ein Komma enthält, stimmt mit
einer Folge von @code{i} oder mehr Übereinstimmungen des Atoms überein. Ein
Atom, gefolgt von einer Begrenzung, die zwei Ganzzahlen @code{i} und
@code{j} Übereinstimmungen enthält, stimmt mit einer Folge von @code{i} bis
@code{j} (inklusive) Übereinstimmungen des Atoms überein.

Beide Argumente müssen im Bereich von @code{0} bis @code{RE_DUP_MAX}
(Vorgabe 255) inklusive sein. Wenn es zwei Argumente gibt, muss das zweite
größer oder gleich dem ersten sein.
@item [a-dX]
@itemx [^a-dX]
Stimmt mit jedem Zeichen überein, was entweder @code{a}, @code{b},
@code{c}, @code{d} oder @code{X} ist (oder nicht ist, wenn ^ benutzt wird).
Um ein literales @code{]}-Zeichen einzuschließen, muss es unmittelbar der
öffnenden Klammer @code{[} folgen. Um ein literales @code{-}-Zeichen
einzuschließen, muss es zuerst oder zuletzt geschrieben werden. Daher
stimmt @code{[0-9]} mit jeder Dezimalziffer überein. Alle Zeichen, die
innerhalb eines @code{[]}-Paars keine definierte Bedeutung haben, haben
keine spezielle Bedeutung und stimmen nur mit sich selbst überein.
@example
mysql> select "aXbc" REGEXP "[a-dXYZ]";         -> 1
mysql> select "aXbc" REGEXP "^[a-dXYZ]$";       -> 0
mysql> select "aXbc" REGEXP "^[a-dXYZ]+$";      -> 1
mysql> select "aXbc" REGEXP "^[^a-dXYZ]+$";     -> 0
mysql> select "gheis" REGEXP "^[^a-dXYZ]+$";    -> 1
mysql> select "gheisa" REGEXP "^[^a-dXYZ]+$";   -> 0
@end example
@item [[.zeichen.]]
Die Zeichenfolge des vereinigten Elements. Die Folge ist ein einzelnes
Element der Ausdrucksliste in der Klammer. Ein Klammerausdruck, der ein
Mehrzeichen-Vereinigungselement enthält, kann daher mit mehr als einem
Zeichen übereinstimmen. Wenn die Vereinigungsfolge zum Beispiel ein
@code{ch}-Vereinigungselement enthält, stimmt der reguläre Ausdruck
@code{[[.ch.]]*c} mit den ersten fünf Zeichen von @code{chchcc} überein.

@item [=zeichen_klasse=]
Eine Äquivalenzklasse, die für Zeichenfolgen aller Vereinigungselemente
dieser steht, inklusive sich selbst.

Wenn zum Beispiel @code{o} und @code{(+)} die Mitglieder einer
Äquivalenzklasse sind, sind @code{[[=o=]]}, @code{[[=(+)=]]} und
@code{[o(+)]} allesamt Synonyme. Eine Äquivalenzklasse darf kein Endpunkt
eines Bereichs sein.

@item [:zeichen_klasse:]
Innerhalb eines Klammerausdrucks steht der Name einer Zeichenklasse, die in
@code{[:} und @code{:]} eingeschlossen ist, für die Auflistung aller
Zeichen, die zu dieser Klasse gehören. Standard-Zeichenklassennamen sind:

@multitable @columnfractions .33 .33 .33
@item alnum @tab digit @tab punct
@item alpha @tab graph @tab space
@item empty @tab lower @tab upper
@item cntrl @tab print @tab xdigit
@end multitable

Diese stehen für die Zeichenklassen, die auf der
@code{ctype(3)}-Handbuchseite definiert sind. Ein Locale darf andere zur
Verfügung stellen. Eine Zeichenklasse darf nicht als Endpunkt eines
Bereichs benutzt werden.
@example
mysql> select "justalnums" REGEXP "[[:alnum:]]+";       -> 1
mysql> select "!!" REGEXP "[[:alnum:]]+";               -> 0
@end example

@item [[:<:]]
@itemx [[:>:]]
Diese stimmen mit der Null-Zeichenkette am Anfang bzw. am Ende eines Worts
überein. Ein Wort ist definiert als Folge von Wort-Zeichen, dem weder
Wortzeichen vorangestellt sind noch darauf folgen. Ein Wortzeichen ist ein
alnum-Zeichen (wie in @code{ctype(3)} definiert) oder ein Unterstrich
(@code{_}).
@example
mysql> select "a word a" REGEXP "[[:<:]]word[[:>:]]";      -> 1
mysql> select "a xword a" REGEXP "[[:<:]]word[[:>:]]";     -> 0
@end example
@end table

@example
mysql> select "weeknights" REGEXP "^(wee|week)(knights|nights)$"; -> 1
@end example


@page
@c This node name ist special



@node GPL license, LGPL license, Regexp, Top
@c German node GPL-Lizenz
@appendix GNU GENERAL PUBLIC LICENSE

@cindex GPL, General Public License
@cindex GPL, GNU General Public License

@center Version 2, Juni 1991

@display
Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA

Jeder hat das Recht, diese Lizenzurkunde zu vervielfältigen und
unveränderte Kopien zu verbreiten; Änderungen sind jedoch nicht gestattet.
@end display

@appendixsec Vorwort

Die meisten Softwarelizenzen sind daraufhin entworfen worden, Ihnen die 
Freiheit zu nehmen, die Software weiterzugeben und zu verändern. 
Im Gegensatz dazu soll Ihnen die GNU General Public License, die 
allgemeine öffentliche GNU-Lizenz, ebendiese Freiheit garantieren. 
Sie soll sicherstellen, dass die Software für alle Benutzer frei ist. 
Diese Lizenz gilt für den Großteil der von der Free Software Foundation 
herausgegebenen Software und für alle anderen Programme, deren Autoren 
ihr Werk dieser Lizenz unterstellt haben. Auch Sie können diese 
Möglichkeit der Lizenzierung für Ihre Programme anwenden. 
(Ein anderer Teil der Software der Free Software Foundation unterliegt 
stattdessen der GNU Library General Public License, der allgemeinen 
öffentlichen GNU-Lizenz für Bibliotheken.)

Die Bezeichnung "freie" Software bezieht sich auf Freiheit, nicht auf 
den Preis. Unsere Lizenzen sollen Ihnen die Freiheit garantieren, 
Kopien freier Software zu verbreiten (und etwas für diesen Service zu 
berechnen, wenn Sie möchten), die Möglichkeit, die Software im Quelltext
zu erhalten oder den Quelltext auf Wunsch zu bekommen. Die Lizenzen 
sollen garantieren, dass Sie die Software ändern oder Teile davon in 
neuen freien Programmen verwenden dürfen - und dass Sie wissen, dass 
Sie dies alles tun dürfen.

Um Ihre Rechte zu schützen, müssen wir Einschränkungen machen, die es 
jedem verbieten, Ihnen diese Rechte zu verweigern oder Sie aufzufordern, 
auf diese Rechte zu verzichten. Aus diesen Einschränkungen folgen 
bestimmte Verantwortlichkeiten für Sie, wenn Sie Kopien der Software 
verbreiten oder sie verändern.

Beispielsweise müssen Sie den Empfängern alle Rechte gewähren, die 
Sie selbst haben, wenn Sie - kostenlos oder gegen Bezahlung - Kopien 
eines solchen Programms verbreiten. Sie müssen sicherstellen, dass auch 
sie den Quelltext erhalten bzw. erhalten können. Und Sie müssen ihnen 
diese Bedingungen zeigen, damit sie Ihre Rechte kennen.

Wir schützen Ihre Rechte in zwei Schritten: (1) Wir stellen die Software 
unter ein Urheberrecht (Copyright), und (2) wir bieten Ihnen diese Lizenz 
an, die Ihnen das Recht gibt, die Software zu vervielfältigen, zu 
verbreiten und/oder zu verändern.

Um die Autoren und uns zu schützen, wollen wir darüberhinaus sicherstellen, 
dass jeder erfährt, dass für diese freie Software keinerlei Garantie besteht. 
Wenn die Software von jemand anderem modifiziert und weitergegeben wird, 
möchten wir, dass die Empfänger wissen, dass sie nicht das Original erhalten 
haben, damit von anderen verursachte Probleme nicht den Ruf des 
ursprünglichen Autors schädigen.

Schließlich und endlich ist jedes freie Programm permanent durch 
Software-Patente bedroht. Wir möchten die Gefahr ausschließen, dass 
Distributoren eines freien Programms individuell Patente lizensieren
 - mit dem Ergebnis, dass das Programm proprietär würde. Um dies zu 
 verhindern, haben wir klargestellt, dass jedes Patent entweder für freie 
Benutzung durch jedermann lizenziert werden muss oder überhaupt nicht 
lizenziert werden darf.

Es folgen die genauen Bedingungen für die Vervielfältigung, 
Verbreitung und Bearbeitung:

@iftex
@appendixsec Bedingungen für die Vervielfältigung, 
Verbreitung und Bearbeitung
@end iftex
@ifinfo
@center GNU GENERAL PUBLIC LICENSE
@center Bedingungen für die Vervielfältigung, Verbreitung 
und Bearbeitung
@end ifinfo

@enumerate 0
@item
Diese Lizenz gilt für jedes Programm und jedes andere Werk, in dem 
ein entsprechender Vermerk des Copyright-Inhabers darauf hinweist, 
dass das Werk unter den Bestimmungen dieser General Public License 
verbreitet werden darf. Im folgenden wird jedes derartige Programm 
oder Werk als "das Programm" bezeichnet; die Formulierung "auf dem 
Programm basierendes Werk" bezeichnet das Programm sowie jegliche 
Bearbeitung des Programms im urheberrechtlichen Sinne, also ein Werk, 
welches das Programm, auch auszugsweise, sei es unverändert oder 
verändert und/oder in eine andere Sprache übersetzt, enthält. 
(Im folgenden wird die Übersetzung ohne Einschränkung als 
"Bearbeitung" eingestuft.) Jeder Lizenznehmer wird im folgenden 
als "Sie" angesprochen.

Andere Handlungen als Vervielfältigung, Verbreitung und Bearbeitung 
werden von dieser Lizenz nicht berührt; sie fallen nicht in Ihren 
Anwendungsbereich. Der Vorgang der Ausführung des Programms wird 
nicht eingeschränkt, und die Ausgaben des Programms unterliegen 
dieser Lizenz nur, wenn der Inhalt ein auf dem Programm basierendes 
Werk darstellt (unabhängig davon, dass die Ausgabe durch die 
Ausführung des Programmes erfolgte). Ob dies zutrifft, hängt von den 
Funktionen des Programms ab.

@item
Sie dürfen auf beliebigen Medien unveränderte Kopien des Quelltextes 
des Programms, wie sie ihn erhalten haben, anfertigen und verbreiten. 
Voraussetzung hierfür ist, dass Sie mit jeder Kopie einen entsprechenden 
Copyright-Vermerk sowie einen Haftungsausschluss veröffentlichen, alle 
Vermerke, die sich auf diese Lizenz und das Fehlen einer Garantie 
beziehen, unverändert lassen und desweiteren allen anderen Empfängern 
des Programms zusammen mit dem Programm eine Kopie dieser Lizenz 
zukommen lassen.

Sie dürfen für den eigentlichen Kopiervorgang eine Gebühr verlangen. 
Wenn Sie es wünschen, dürfen Sie auch gegen Entgelt eine Garantie 
für das Programm anbieten.

@item
Sie dürfen Ihre Kopie(n) des Programms oder eines Teils davon 
verändern, wodurch ein auf dem Programm basierendes Werk entsteht; 
Sie dürfen derartige Bearbeitungen unter den Bestimmungen von 
Paragraph 1 vervielfältigen und verbreiten, vorausgesetzt, dass 
zusätzlich alle folgenden Bedingungen erfüllt werden:

@enumerate a
@item
Sie müssen die veränderten Dateien mit einem auffälligen Vermerk 
versehen, der auf die von Ihnen vorgenommene Modifizierung und 
das Datum jeder Änderung hinweist.

@item
Sie müssen dafür sorgen, dass jede von Ihnen verbreitete oder 
veröffentlichte Arbeit, die ganz oder teilweise von dem Programm 
oder Teilen davon abgeleitet ist, Dritten gegenüber als Ganzes 
unter den Bedingungen dieser Lizenz ohne Lizenzgebühren zur 
Verfügung gestellt wird.

@item
Wenn das veränderte Programm normalerweise bei der Ausführung 
interaktiv Kommandos einliest, müssen Sie dafür sorgen, dass es, 
wenn es auf dem üblichsten Wege für solche interaktive Nutzung 
gestartet wird, eine Meldung ausgibt oder ausdruckt, die einen 
geeigneten Copyright-Vermerk enthält sowie einen Hinweis, dass es 
keine Gewährleistung gibt (oder anderenfalls, dass Sie Garantie 
leisten), und dass die Benutzer das Programm unter diesen 
Bedingungen weiter verbreiten dürfen. Auch muss der Benutzer darauf
hingewiesen werden, wie er eine Kopie dieser Lizenz ansehen kann.
(Ausnahme: Wenn das Programm selbst interaktiv arbeitet, aber 
normalerweise keine derartige Meldung ausgibt, muss Ihr auf dem 
Programm basierendes Werk auch keine solche Meldung ausgeben).
@end enumerate

Diese Anforderungen betreffen das veränderte Werk als Ganzes. 
Wenn identifizierbare Abschnitte des Werkes nicht von dem 
Programm abgeleitet sind und vernünftigerweise selbst als 
unabhängige und eigenständige Werke betrachtet werden können, dann 
erstrecken sich diese Lizenz und Ihre Bedingungen nicht auf 
diese Abschnitte, wenn sie als eigenständige Werke verbreitet 
werden. Wenn Sie jedoch dieselben Abschnitte als Teil eines 
Ganzen verbreiten, dass ein auf dem Programm basierendes Werk 
darstellt, dann muss die Verbreitung des Ganzen nach den 
Bedingungen dieser Lizenz erfolgen, deren Bedingungen für 
weitere Lizenznehmer somit auf die Gesamtheit ausgedehnt werden 
- und damit auf jeden einzelnen Teil, unabhängig vom jeweiligen Autor.

Somit ist es nicht die Absicht dieses Abschnittes, Rechte für 
Werke in Anspruch zu nehmen oder zu beschneiden, die komplett 
von Ihnen geschrieben wurden; vielmehr ist es die Absicht, 
die Rechte zur Kontrolle der Verbreitung von Werken, die auf 
dem Programm basieren oder unter seiner auszugsweisen 
Verwendung zusammengestellt worden sind, auszuüben.

Ferner bringt ein einfaches Zusammenstellen eines anderen Werkes, 
das nicht auf dem Programm basiert, zusammen mit dem Programm 
oder einem auf dem Programm basierenden Werk auf ein- und 
demselben Speicher- oder Vertriebsmedium das andere Werk nicht in 
den Anwendungsbereich dieser Lizenz.

@item
Sie dürfen das Programm (oder ein darauf basierendes Werk gemäß 
Paragraph 2) als Objectcode oder in ausführbarer Form unter den 
Bedingungen von Paragraph 1 und 2 vervielfältigen und verbreiten 
- vorausgesetzt, dass Sie außerdem eine der folgenden Leistungen 
erbringen:

@enumerate a
@item
Liefern Sie das Programm zusammen mit dem vollständigen 
zugehörigen maschinenlesbaren Quelltext auf einem für den 
Datenaustausch üblichen Medium aus, wobei die Verteilung unter den 
Bedingungen der Paragraphen 1 und 2 erfolgen muß. Oder:

@item
Liefern Sie das Programm zusammen mit einem mindestens drei 
Jahre lang gültigen schriftlichen Angebot aus, jedem Dritten 
eine vollständige maschinenlesbare Kopie des Quelltextes zur 
Verfügung zu stellen - zu nicht höheren Kosten als denen, die 
durch den physikalischen Kopiervorgang anfallen -, wobei der 
Quelltext unter den Bedingungen der Paragraphen 1 und 2 auf 
einem für den Datenaustausch üblichen Medium weitergegeben 
wird. Oder:

@item
Liefern Sie das Programm zusammen mit dem schriftlichen An-
gebot der Zurverfügungstellung des Quelltextes aus, das Sie 
selbst erhalten haben. (Diese Alternative ist nur für 
nicht-kommerzielle Verbreitung zulässig und nur, wenn Sie 
das Programm als Objectcode oder in ausführbarer Form mit 
einem entsprechenden Angebot gemäß Absatz b erhalten haben.)
@end enumerate

Unter dem Quelltext eines Werkes wird diejenige Form des Werkes 
verstanden, die für Bearbeitungen vorzugsweise verwendet wird. 
Für ein ausführbares Programm bedeutet "der komplette Quell-
text": Der Quelltext aller im Programm enthaltenen Module ein-
schließlich aller zugehörigen Modulschnittstellen-Definitions-
dateien sowie der zur Compilation und Installation verwendeten 
Skripte. Als besondere Ausnahme jedoch braucht der verteilte 
Quelltext nichts von dem zu enthalten, was üblicherweise 
(entweder als Quelltext oder in binärer Form) zusammen mit den 
Hauptkomponenten des Betriebssystems (Kernel, Compiler usw.) 
geliefert wird, unter dem das Programm läuft - es sei denn, 
diese Komponente selbst gehört zum ausführbaren Programm.

Wenn die Verbreitung eines ausführbaren Programms oder des 
Objectcodes dadurch erfolgt, dass der Kopierzugriff auf eine 
dafür vorgesehene Stelle gewährt wird, so gilt die Gewährung 
eines gleichwertigen Zugriffs auf den Quelltext als Verbreitung 
des Quelltextes, auch wenn Dritte nicht dazu gezwungen sind, 
den Quelltext zusammen mit dem Objectcode zu kopieren.

@item
Sie dürfen das Programm nicht vervielfältigen, verändern, weiter 
lizenzieren oder verbreiten, sofern es nicht durch diese Lizenz 
ausdrücklich gestattet ist. Jeder anderweitige Versuch der 
Vervielfältigung, Modifizierung, Weiterlizenzierung und Verbreitung
ist nichtig und beendet automatisch Ihre Rechte unter dieser 
Lizenz. Jedoch werden die Lizenzen Dritter, die von Ihnen Kopien
oder Rechte unter dieser Lizenz erhalten haben, nicht beendet, 
solange diese die Lizenz voll anerkennen und befolgen.

@item
Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da Sie sie 
nicht unterzeichnet haben. Jedoch gibt Ihnen nichts anderes die 
Erlaubnis, das Programm oder von ihm abgeleitete Werke zu 
verändern oder zu verbreiten. Diese Handlungen sind gesetzlich 
verboten, wenn Sie diese Lizenz nicht anerkennen. Indem Sie das 
Programm (oder ein darauf basierendes Werk) verändern oder 
verbreiten, erklären Sie Ihr Einverständnis mit dieser Lizenz und 
mit allen Ihren Bedingungen bezüglich der Vervielfältigung, 
Verbreitung und Veränderung des Programms oder eines darauf 
basierenden Werkes.

@item
Jedesmal, wenn Sie das Programm (oder ein auf dem Programm 
basierendes Werk) weitergeben, erhält der Empfänger automatisch 
vom ursprünglichen Lizenzgeber die Lizenz, das Programm 
entsprechend den hier festgelegten Bestimmungen zu vervielfältigen, 
zu verbreiten und zu verändern. Sie dürfen keine weiteren 
Einschränkungen der Durchsetzung der hierin zugestandenen Rechte 
des Empfängers vornehmen. Sie sind nicht dafür verantwortlich, 
die Einhaltung dieser Lizenz durch Dritte durchzusetzen.

@item
Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs einer 
Patentverletzung oder aus einem anderen Grunde (nicht auf Patent
fragen begrenzt) Bedingungen (durch Gerichtsbeschluß, Vergleich 
oder anderweitig) auferlegt werden, die den Bedingungen dieser 
Lizenz widersprechen, so befreien Sie diese Umstände nicht von 
den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht möglich ist, 
das Programm unter gleichzeitiger Beachtung der Bedingungen in 
dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu ver-
breiten, dann dürfen Sie als Folge das Programm überhaupt nicht 
verbreiten. Wenn zum Beispiel ein Patent nicht die gebührenfreie 
Weiterverbreitung des Programms durch diejenigen erlaubt, die das
Programm direkt oder indirekt von Ihnen erhalten haben, dann 
besteht der einzige Weg, sowohl das Patentrecht als auch diese 
Lizenz zu befolgen, darin, ganz auf die Verbreitung des Programms
zu verzichten.

Sollte sich ein Teil dieses Paragraphen als ungültig oder unter 
bestimmten Umständen nicht durchsetzbar erweisen, so soll dieser 
Paragraph seinem Sinne nach angewandt werden; im übrigen soll 
dieser Paragraph als Ganzes gelten.

Zweck dieses Paragraphen ist nicht, Sie dazu zu bringen, 
irgendwelche Patente oder andere Eigentumsansprüche zu verletzen oder 
die Gültigkeit solcher Ansprüche zu bestreiten; dieser Paragraph 
hat einzig den Zweck, die Integrität des Verbreitungssystems der 
freien Software zu schützen, das durch die Praxis öffentlicher 
Lizenzen verwirklicht wird. Viele Leute haben großzügige Beiträge
zu dem großen Angebot der mit diesem System verbreiteten Software
im Vertrauen auf die konsistente Anwendung dieses Systems 
geleistet; es liegt am Autor/Geber, zu entscheiden, ob er die 
Software mittels irgendeines anderen Systems verbreiten will; ein 
Lizenznehmer hat auf diese Entscheidung keinen Einfluss.

Dieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als 
Konsequenz aus dem Rest dieser Lizenz betrachtet wird.

@item
Wenn die Verbreitung und/oder die Benutzung des Programms in be-
stimmten Staaten entweder durch Patente oder durch urheberrechtlich 
geschützte Schnittstellen eingeschränkt ist, kann der Urheberrechts-
inhaber, der das Programm unter diese Lizenz gestellt hat, eine 
explizite geographische Beschränkung der Verbreitung angeben, in der 
diese Staaten ausgeschlossen werden, so dass die Verbreitung nur 
innerhalb und zwischen den Staaten erlaubt ist, die nicht ausge-
schlossen sind. In einem solchen Fall beinhaltet diese Lizenz die 
Beschränkung, als wäre sie in diesem Text niedergeschrieben.

@item
Die Free Software Foundation kann von Zeit zu Zeit überarbeitete 
und/oder neue Versionen der General Public License veröffentlichen. 
Solche neuen Versionen werden vom Grundprinzip her der gegenwärtigen 
entsprechen, können aber im Detail abweichen, um neuen Problemen und 
Anforderungen gerecht zu werden.

Jede Version dieser Lizenz hat eine eindeutige Versionsnummer. 
Wenn in einem Programm angegeben wird, dass es dieser Lizenz in einer 
bestimmten Versionsnummer oder "jeder späteren Version" ("any later 
version") unterliegt, so haben Sie die Wahl, entweder den Bestimmungen 
der genannten Version zu folgen oder denen jeder beliebigen späteren 
Version, die von der Free Software Foundation veröffentlicht wurde. 
Wenn das Programm keine Versionsnummer angibt, können Sie eine beliebige 
Version wählen, die je von der Free Software Foundation veröffentlicht 
wurde.

@item
Wenn Sie den Wunsch haben, Teile des Programms in anderen freien Programmen 
zu verwenden, deren Bedingungen für die Verbreitung anders sind, schreiben 
Sie an den Autor, um ihn um die Erlaubnis zu bitten. Für Software, die unter 
dem Copyright der Free Software Foundation steht, schreiben Sie an die Free 
Software Foundation; wir machen zu diesem Zweck gelegentlich Ausnahmen. 
Unsere Entscheidung wird von den beiden Zielen geleitet werden, zum einen 
den freien Status aller von unserer freien Software abgeleiteten Werke zu 
erhalten und zum anderen das gemeinschaftliche Nutzen und Wiederverwenden 
von Software im allgemeinen zu fördern

@iftex
@heading Keine Gewährleistung
@end iftex
@ifinfo
@center Keine Gewährleistung
@end ifinfo

@item
Da das Programm ohne jegliche Kosten lizenziert wird, besteht keinerlei 
Gewährleistung für das Programm, soweit dies gesetzlich zulässig ist. 
Sofern nicht anderweitig schriftlich bestätigt, stellen die Copyright-Inhaber 
und/oder Dritte das Programm so zur Verfügung, "wie es ist", ohne irgendeine 
Gewährleistung, weder ausdrücklich noch implizit, einschließlich - aber nicht 
begrenzt auf - Marktreife oder Verwendbarkeit für einen bestimmten Zweck. 
Das volle Risiko bezüglich Qualität und Leistungsfähigkeit des Programms 
liegt bei Ihnen. Sollte sich das Programm als fehlerhaft herausstellen, 
liegen die Kosten für notwendigen Service, Reparatur oder Korrektur bei Ihnen.

@item
In keinem Fall, außer wenn durch geltendes Recht gefordert oder schriftlich 
zugesichert, ist irgendein Copyright-Inhaber oder irgendein Dritter, der das 
Programm wie oben erlaubt modifiziert oder verbreitet hat, Ihnen gegenüber 
für irgendwelche Schäden haftbar, einschließlich jeglicher allgemeiner oder 
spezieller Schäden, Schäden durch Seiteneffekte (Nebenwirkungen) oder 
Folgeschäden, die aus der Benutzung des Programms oder der Unbenutzbarkeit des 
Programms folgen (einschließlich - aber nicht beschränkt auf - Datenverluste, 
fehlerhafte Verarbeitung von Daten, Verluste, die von Ihnen oder anderen 
getragen werden müssen oder dem Unvermögen des Programms, mit irgendeinem 
anderen Programm zusammenzuarbeiten), selbst wenn ein Copyright-Inhaber 
oder Dritter über die Möglichkeit solcher Schäden unterrichtet worden war.
@end enumerate

@iftex
@heading Ende der Bedingungen
@end iftex
@ifinfo
@center Ende der Bedingungen
@end ifinfo

@page
@appendixsec Anhang: Wie Sie diese Bedingungen auf Ihre neuen Programme anwendbar machen

Wenn Sie ein neues Programm entwickeln und wollen, dass es von größtmöglichem 
Nutzen für die Allgemeinheit ist, dann erreichen Sie das am besten, indem 
Sie es zu freier Software machen, die jeder unter diesen Bestimmungen 
weiterverbreiten und verändern kann.

Um dies zu erreichen, fügen Sie die folgenden Anmerkungen zu Ihrem Programm 
hinzu. Am sichersten ist es, sie an den Anfang einer jeden Quelldatei zu 
stellen, um den Gewährleistungsausschluß möglichst deutlich darzustellen; 
außerdem sollte jede Datei mindestens eine "Copyright"-Zeile besitzen sowie 
einen kurzen Hinweis darauf, wo die vollständige Lizenz gefunden werden kann.

@smallexample
@var{eine Zeile mit dem Programmnamen und einer kurzen Beschreibung}
Copyright (C) @var{yyyy}  @var{Name des Autors}

This Programm ist free Software; you can redistribute it und / oder modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License oder
(at your option) any later version.

This Programm ist distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; ohne even the implied warranty of
MERCHANTABILITY oder FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License für mehr details.

You should have received a copy of the GNU General Public License
along mit this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@end smallexample

Also add information on how to contact you von electronic und paper mail.

@smallexample auf deutsch
@var{eine Zeile mit dem Programmnamen und einer kurzen Beschreibung}
Copyright (C) @var{yyyy}  @var{Name des Autors}

    Dieses Programm ist freie Software. Sie können es unter
    den Bedingungen der GNU General Public License, wie von der
    Free Software Foundation herausgegeben, weitergeben und/oder
    modifizieren, entweder unter Version 2 der Lizenz oder (wenn
    Sie es wünschen) jeder späteren Version.

    Die Veröffentlichung dieses Programms erfolgt in der
    Hoffnung, dass es Ihnen von Nutzen sein wird, aber OHNE JEDE
    GEWÄHRLEISTUNG - sogar ohne die implizite Gewährleistung
    der MARKTREIFE oder der EIGNUNG FÜR EINEN BESTIMMTEN ZWECK.
    Details finden Sie in der GNU General Public License.

    Sie sollten eine Kopie der GNU General Public License zusammen
    mit diesem Programm erhalten haben. Falls nicht, schreiben Sie
    an die Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
    MA 02139, USA.
@end smallexample


Wenn Ihr Programm interaktiv ist, sorgen Sie dafür, dass es nach dem 
Start einen kurzen Vermerk ausgibt:

@smallexample
Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author}
Gnomovision comes mit ABSOLUTELY NO WARRANTY; für details type `show w'.
Das ist free Software und you are welcome to redistribute it
under certain conditions; type `show c' für details.
@end smallexample

@smallexample auf deutsch
    Gnomovision Version 69, Copyright (C) 19[jj]  [Name des Autors]
    Für Gnomovision besteht KEINERLEI GARANTIE; geben Sie `show w'
    für Details ein. Gnomovision ist freie Software, die Sie unter
    bestimmten Bedingungen weitergeben dürfen; geben Sie `show c'
    für Details ein.
@end smallexample

Die hypothetischen Kommandos `show w' und `show c' sollten die 
entsprechenden Teile der GNU-GPL anzeigen. Natürlich können die von 
Ihnen verwendeten Kommandos anders heißen als `show w' und `show c'; 
es könnten auch Mausklicks oder Menüpunkte sein - was immer am besten 
in Ihr Programm passt.

Soweit vorhanden, sollten Sie auch Ihren Arbeitgeber (wenn Sie als 
Programmierer arbeiten) oder Ihre Schule einen Copyright-Verzicht 
für das Programm unterschreiben lassen. Hier ein Beispiel; 
ändern Sie bitte die Namen:

@example
Yoyodyne, Inc., herefrom disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.

@var{signature of Ty Coon}, 1 April 1989
Ty Coon, President of Vice
@end example

@example auf deutsch
Die Yoyodyne GmbH erhebt keinerlei urheberrechtlichen Anspruch auf das 
Programm "Gnomovision" (einem Schrittmacher für Compiler), 
geschrieben von James Hacker.

@var{Unterschrift von Ty Coon}, 1 April 1989
Ty Coon, Vizepräsident
@end example

Diese General Public License gestattet nicht die Einbindung des Programms 
in proprietäre Programme. Ist Ihr Programm eine Funktionsbibliothek, so 
kann es sinnvoller sein, das Linken proprietärer Programme mit dieser 
Bibliothek zu gestatten. Wenn Sie dies tun wollen, sollten Sie die 
GNU Library General Public License anstelle dieser Lizenz verwenden.

@display
@c German FIX added @@ in e-mail addresses
Erstellt im Auftrag der S.u.S.E. GmbH [suse@@suse.de]
von Katja Lachmann Übersetzungen [na194@@fim.uni-erlangen.de],
überarbeitet von Peter Gerwinski [peter.gerwinski@@uni-essen.de] (31. Oktober 1996) 

Diese Übersetzung wird mit der Absicht angeboten, das Verständnis der 
GNU General Public License (GNU-GPL) zu erleichtern. Es handelt sich jedoch 
nicht um eine offizielle oder im rechtlichen Sinne anerkannte Übersetzung.

Die Free Software Foundation (FSF) ist nicht der Herausgeber dieser Übersetzung, 
und sie hat diese Übersetzung auch nicht als rechtskräftigen Ersatz für die 
Original-GNU-GPL anerkannt. Da die Übersetzung nicht sorgfältig von Anwälten 
überprüft wurde, können die Übersetzer nicht garantieren, dass die Übersetzung 
die rechtlichen Aussagen der GNU-GPL exakt wiedergibt. Wenn Sie sichergehen 
wollen, dass von Ihnen geplante Aktivitäten im Sinne der GNU-GPL gestattet sind, 
halten Sie sich bitte an die englischsprachige Originalversion.

Die Free Software Foundation möchte Sie darum bitten, diese Übersetzung 
nicht als offizielle Lizenzbedingungen für von Ihnen geschriebene Programme 
zu verwenden. Bitte benutzen Sie hierfür stattdessen die von der 
Free Software Foundation herausgegebene englischsprachige Originalversion.
@end display

@page




@node LGPL license, Function Index, GPL license, Top
@c German node LGPL-Lizenz
@appendix GNU LESSER GENERAL PUBLIC LICENSE

@cindex LGPL, Lesser General Public License
@cindex LGPL, GNU Library General Public License

@center Version 2.1, Februar 1999

@display
Copyright @copyright{} 1991, 1999 Free Software Foundation, Inc.
59 Temple Place -- Suite 330, Boston, MA 02111-1307, USA

Es ist jedermann gestattet, diese Lizenzurkunde zu vervielfältigen 
und unveränderte Kopien zu verbreiten. Änderungen sind jedoch nicht erlaubt. 

[Dies ist die erste freigegebene Version der Lesser GPL. 
Sie ist als Nachfolgerin der GNU Library Public License zu betrachten und 
erhielt daher die Versionsnummer 2.1.]
@end display

Diese Übersetzung ist kein rechtskräftiger Ersatz für die 
englischsprachige Originalversion! 

@appendixsec Vorwort

Die meisten Softwarelizenzen sind daraufhin entworfen worden, Ihnen die 
Freiheit zu nehmen, die Software weiterzugeben und zu verändern. 
Im Gegensatz dazu sollen Ihnen die GNU General Public Licenses, 
die Allgemeinen Öffentlichen GNU-Lizenzen, ebendiese Freiheit des 
Weitergebens und Veränderns garantieren und somit sicherstellen, dass diese 
Software für alle Benutzer frei ist. 

Diese Lizenz, die Kleine Allgemeine Öffentliche Lizenz 
(Lesser General Public License), gilt für einige besonders bezeichnete 
Software-Pakete - typischerweise Programmbibliotheken - von der 
Free Software Foundation und anderen Autoren, die beschließen, 
diese Lizenz zu verwenden. Auch Sie können sie verwenden; wir empfehlen 
aber, vorher gründlich darüber nachzudenken, ob diese Lizenz (LGPL) 
oder aber die gewöhnliche Allgemeine Öffentliche Lizenz (GPL) die 
bessere Strategie zur Anwendung im jeweiligen speziellen Fall ist. 
Dabei bieten Ihnen die untenstehenden Erläuterungen eine Grundlage 
für Ihre Entscheidung. 

Die Bezeichnung ,,freie`` Software bezieht sich auf Freiheit der Nutzung, 
nicht auf den Preis. Unsere Allgemeinen Öffentlichen Lizenzen sollen 
sicherstellen, dass Sie die Freiheit haben, Kopien freier Software zu 
verbreiten (und etwas für diesen Service zu berechnen, wenn Sie möchten), 
dass Sie die Software im Quelltext erhalten oder den Quelltext auf Wunsch 
bekommen können, dass Sie die Software ändern oder Teile davon in neuen 
freien Programmen verwenden dürfen, und dass Sie darüber informiert sind, 
dass Sie dies alles tun dürfen. 

Um Ihre Rechte zu schützen, müssen wir Einschränkungen machen, die es jedem, 
der die Software weitergibt, verbieten, Ihnen diese Rechte zu verweigern 
oder Sie zum Verzicht auf diese Rechte aufzufordern. Aus diesen 
Einschränkungen ergeben sich bestimmte Verantwortlichkeiten für Sie, wenn Sie 
Kopien der Bibliothek verbreiten oder sie verändern. 

Beispielsweise müssen Sie den Empfängern alle Rechte gewähren, die wir Ihnen 
eingeräumt haben, wenn Sie - kostenlos oder gegen Bezahlung - Kopien der 
Bibliothek verbreiten. Sie müssen sicherstellen, dass auch die Empfänger 
den Quelltext erhalten bzw. erhalten können. Wenn Sie einen anderen Code 
mit der Bibliothek linken, müssen Sie den Empfängern die vollständigen 
Objekt-Dateien zukommen lassen, so dass sie selbst diesen Code mit der 
Bibliothek neu linken können, auch nachdem sie Veränderungen an der 
Bibliothek vorgenommen und sie neu compiliert haben. Und Sie müssen ihnen 
diese Bedingungen zeigen, damit sie Ihre Rechte kennen. 

Wir schützen Ihre Rechte in zwei Schritten: (1) Wir stellen die Bibliothek 
unter ein Urheberrecht (Copyright), und (2) wir bieten Ihnen diese Lizenz 
an, die Ihnen das Recht gibt, die Bibliothek zu vervielfältigen, zu 
verbreiten und/oder zu verändern. 

Um jeden, der die Software weitergibt, zu schützen, wollen wir darüber 
hinaus vollkommen klarstellen, dass für diese freie Bibliothek keinerlei 
Garantie besteht. Auch sollten, falls die Software von jemand anderem 
modifiziert und weitergegeben wird, die Empfänger wissen, dass sie nicht 
das Original erhalten haben, damit irgendwelche von anderen verursachte 
Probleme nicht den Ruf des ursprünglichen Autors schädigen. 

Schließlich und endlich stellen Software-Patente für die Existenz jedes 
freien Programms eine ständige Bedrohung dar. Wir möchten sicherstellen, 
dass keine Firma den Benutzern eines freien Programms Einschränkungen 
auferlegen kann, indem sie von einem Patentinhaber eine die freie Nutzung 
einschränkende Lizenz erwirbt. Deshalb bestehen wir darauf, dass jegliche 
für eine Version der Bibliothek erworbene Patentlizenz mit der in dieser 
Lizenz (also der LGPL) im einzelnen angegebenen Nutzungsfreiheit voll 
vereinbar sein muß. 

Die meiste GNU-Software einschließlich einiger Bibliotheken fällt unter 
die gewöhnliche Allgemeine Öffentliche GNU-Lizenz (GNU-GPL). 
Die vorliegende Lizenz, also die GNU-LGPL, gilt für gewisse näher 
bezeichnete Bibliotheken. Sie unterscheidet sich wesentlich von der 
gewöhnlichen Allgemeinen Öffentlichen Lizenz (GNU-GPL). Wir benutzen 
diese Lizenz für gewisse Bibliotheken, um das Linken (d.h. die Verknüpfung 
von Bibliotheken und anderen Programmteilen zu einem lauffähigen 
Programm - Anmerkung der Übersetzer) von Programmen, die nicht frei 
sind, mit diesen Bibliotheken zu gestatten. 

Wenn ein Programm mit einer Bibliothek gelinkt wurde, sei es nun statisch 
oder dynamisch, so ist die Kombination der beiden, rechtlich gesehen, 
ein ,,kombiniertes Datenwerk``, also eine abgeleitete Version der 
Orginal-Bibliothek. Die gewöhnliche GPL erlaubt ein solches Linken nur 
dann, wenn die ganze Kombination die Kriterien für freie Software erfüllt. 
Die LGPL erlaubt dagegen weniger strenge Kriterien für das Linken von 
irgendeiner anderen Software mit der Bibliothek. 

Wir nennen diese Lizenz die "Kleine" Allgemeine Öffentliche Lizenz 
@dfn{Lesser} General Public License weil sie weniger  @emph{Less} dazu beiträgt, 
die Freiheit des Benutzers zu schützen, als die gewöhnliche Allgemeine 
Öffentliche Lizenz (GPL). Sie verschafft auch anderen Entwicklern freier 
Software ein "Weniger" an Vorteil gegenüber konkurrierenden nichtfreien Programmen. 
Diese Nachteile sind ein Grund dafür, dass wir die gewöhnliche GPL für viele 
Bibliotheken benutzen. Die "kleine" Lizenz (LGPL) bietet aber unter bestimmten 
besonderen Umständen doch Vorteile. 

So kann, wenn auch nur bei seltenen Gelegenheiten, eine besondere Notwendigkeit 
bestehen, einen Anreiz zur möglichst weitgehenden Benutzung einer bestimmten 
Bibliothek zu schaffen, so dass diese dann ein De-facto-Standard wird. Um dies 
zu erreichen, müssen nichtfreie Programme die Bibliothek benutzen dürfen. 
Ein häufigerer Fall ist der, dass eine freie Bibliothek dasselbe leistet wie 
weithin benutzte nichtfreie Bibliotheken. In diesem Falle bringt es wenig 
Nutzen, die freie Bibliothek allein auf freie Software zu beschränken, und 
dann benutzen wir eben die LGPL. 

In anderen Fällen ermöglicht die Erlaubnis zur Benutzung einer speziellen 
Bibliothek in nichtfreien Programmen viel mehr Leuten, eine umfangreiche 
Sammlung freier Software zu nutzen. So ermöglicht z.B. die Erlaubnis zur 
Benutzung der GNU-C-Bibliothek in nichtfreien Programmen einer viel größeren 
Zahl von Leuten, das ganze GNU-Betriebssystem ebenso wie seine Variante, das 
Betriebssystem GNU/Linux, zu benutzen. 

Obwohl die LGPL die Freiheit des Benutzers weniger schützt, stellt sie doch 
sicher, dass der Benutzer eines Programms, das mit der Bibliothek gelinkt wurde, 
die Freiheit und die erforderlichen Mittel hat, das Programm unter Benutzung 
einer abgeänderten Version der Bibliothek zu betreiben. 

Die genauen Bedingungen für das Kopieren, Weitergeben und Abändern finden Sie 
im nachstehenden Kapitel. Achten Sie genau auf den Unterschied zwischen 
"work Basiert auf the library", d.h. "Datenwerk, das auf der Bibliothek basiert"
und "work that uses the library" d.h. "Datenwerk, das die Bibliothek benutzt".
Ersteres enthält Code, der von der Bibliothek abgeleitet ist, während letzteres 
lediglich mit der Bibliothek kombiniert werden muß, um betriebsfähig zu sein. 

@iftex
@appendixsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
@end iftex
@ifinfo
@center GNU LESSER GENERAL PUBLIC LICENSE
@center Bedingungen für die Vervielfältigung, Verbreitung und Bearbeitung 

@end ifinfo

@enumerate 0
@item
Diese Lizenz gilt für jedes Programm und jedes andere Datenwerk, in dem 
ein entsprechender Vermerk des Copyright-Inhabers oder eines anderen dazu 
Befugten darauf hinweist, dass das Datenwerk unter den Bestimmungen dieser 
Lesser General Public License (im weiteren auch als "diese Lizenz" 
bezeichnet) verbreitet werden darf. Jeder Lizenznehmer wird hierin 
einfach als "Sie" angesprochen. 

Eine "Bibliothek" bedeutet eine Zusammenstellung von Software-Funktionen 
und/oder Daten, die so vorbereitet ist, dass sie sich bequem mit 
Anwendungsprogrammen (welche einige dieser Funktionen und Daten benutzen) zum Bilden 
von ausführbaren Programmen linken (d.h. verbinden, kombinieren) läßt. 

Der Begriff "Bibliothek" bezieht sich im weiteren immer nur auf solche 
Software-Bibliotheken und solche Datenwerke, die unter diesen Bedingungen 
der Lesser-GPL-Lizenz verbreitet worden sind. Ein "auf der Bibliothek 
basierendes Datenwerk" bezeichnet die betreffende Bibliothek selbst 
sowie jegliche davon abgeleitete Bearbeitung im urheberrechtlichen Sinne, 
also ein Datenwerk, welches die Bibliothek oder einen Teil davon, sei 
es unverändert oder verändert und/oder direkt in eine andere Sprache 
übersetzt, enthält. (Im folgenden wird die Übersetzung ohne 
Einschränkung als "Bearbeitung" eingestuft.) 

Unter dem "Quelltext" eines Datenwerks ist seine für das Vornehmen 
von Veränderungen bevorzugte Form zu verstehen. Für eine Bibliothek 
bedeutet "vollständiger Quelltext" den gesamten Quelltext für alle in 
ihr enthaltenen Bestandteile, für jegliche zu ihr gehörenden Dateien 
zur Definition von Schnittstellen und schließlich auch für die Skripte, 
die zur Steuerung der Compilation und Installation der Bibliothek 
benutzt werden. 

Andere Handlungen als Vervielfältigung, Verbreitung und Bearbeitung 
werden von dieser Lizenz nicht berührt; sie fallen nicht in Ihren 
Anwendungsbereich. Das Ausführen eines Programms unter Benutzung der 
Bibliothek wird nicht eingeschränkt, und die Ausgaben des Programms 
unterliegen dieser Lizenz nur dann, wenn der Inhalt ein auf der 
Bibliothek basierendes Datenwerk darstellt (unabhängig davon, dass die 
Bibliothek in einem Werkzeug zum Schreiben dieses Programms benutzt 
wurde). Ob dies zutrifft, hängt davon ab, was die Bibliothek bewirkt 
und was das Programm, das die Bibliothek nutzt, bewirkt. 

@item
Sie dürfen auf beliebigen Medien unveränderte Kopien des vollständigen 
Quelltextes des Programms so, wie sie ihn erhalten haben, anfertigen 
und verbreiten. Voraussetzung hierfür ist, dass Sie mit jeder Kopie 
deutlich erkennbar und in angemessener Form einen entsprechenden 
Copyright-Vermerk sowie einen Haftungsausschluss veröffentlichen, alle 
Vermerke, die sich auf diese Lizenz und das Fehlen einer Garantie 
beziehen, unverändert lassen und zusammen mit der Bibliothek jeweils 
eine Kopie dieser Lizenz weitergeben. 

Sie dürfen für den eigentlichen Kopier- und Versandvorgang eine Gebühr 
verlangen. Wenn Sie es wünschen, dürfen Sie auch gegen Entgelt eine 
Garantie anbieten. 

@item
Sie dürfen Ihre Kopie(n) der Bibliothek oder irgendeines Teils davon 
verändern, wodurch ein auf der Bibliothek basierendes Datenwerk 
entsteht, und Sie dürfen derartige Bearbeitungen unter den Bestimmungen
von Paragraph 1 vervielfältigen und verbreiten, vorausgesetzt, dass 
zusätzlich alle im folgenden genannten Bedingungen erfüllt werden: 

@enumerate a
@item
Das Bearbeitungsergebnis muss selbst wieder eine Software-Bibliothek sein. 

@item
Sie müssen die veränderten Dateien mit einem auffälligen Vermerk 
versehen, der auf die von Ihnen vorgenommene Modifizierung der 
Dateien hinweist und das Datum jeder Änderung angibt. 

@item
Sie müssen dafür sorgen, dass das Datenwerk als Ganzes Dritten unter 
den Bedingungen dieser Lizenz ohne Lizenzgebühren zur Verfügung 
gestellt wird. 

@item
Wenn sich eine Funktionseinheit der bearbeiteten Bibliothek auf eine 
Funktion oder Datentabelle stützt, die von einem die Funktionseinheit 
nutzenden Anwendungsprogramm bereitgestellt werden muß, ohne dass sie 
als Argument übergeben werden muß, wenn die Funktionseinheit angesprochen 
wird, dann müssen Sie sich nach bestem Wissen und Gewissen bemühen, 
sicherzustellen, dass die betreffende Funktionseinheit auch dann noch 
funktioniert, wenn die Anwendung eine solche Funktion oder Datentabelle 
nicht bietet, und dass sie den sinnvoll bleibenden Teil Ihres 
Bestimmungszwecks noch ausführt. 

(So hat z.B. eine Funktion zum Berechnen von Quadratwurzeln einen von 
der Anwendung unabhängigen genau definierten Zweck. Deshalb verlangt 
§2 Absatz d, dass jede von der Anwendung bereitgestellte Funktion oder 
von dieser Funktion benutzte Tabelle optional sein muß: Auch wenn die 
Anwendung sie nicht bereitstellt, muss die Quadratwurzelfunktion trotzdem 
noch Quadratwurzeln berechnen). 
@end enumerate

Diese Anforderungen gelten für das bearbeitete Datenwerk als Ganzes. 
Wenn identifizierbare Teile davon nicht von der Bibliothek stammen und 
vernünftigerweise als unabhängige und gesonderte Datenwerke für sich selbst 
zu betrachten sind, dann gelten diese Lizenz und Ihre Bedingungen nicht 
für die betreffenden Teile, wenn Sie diese als gesonderte Datenwerke 
weitergeben. Wenn Sie jedoch dieselben Teile als Teil eines Ganzen 
weitergeben, dass ein auf der Bibliothek basierendes Datenwerk darstellt, 
dann muss die Weitergabe dieses Ganzen nach den Bedingungen dieser Lizenz 
erfolgen, deren Bedingungen für weitere Lizenznehmer somit auf das 
gesamte Ganze ausgedehnt werden - und somit auf jeden einzelnen Teil, 
unabhängig vom jeweiligen Autor. 

Somit ist es nicht die Absicht dieses Abschnittes, Rechte für Datenwerke
in Anspruch zu nehmen oder Ihnen Rechte für Datenwerke streitig zu 
machen, die komplett von Ihnen geschrieben wurden; vielmehr ist es die 
Absicht, die Rechte zur Kontrolle der Verbreitung von Datenwerken, die 
auf der Bibliothek basieren oder unter Ihrer auszugsweisen Verwendung 
zusammengestellt worden sind, auszuüben. 

Ferner bringt auch dass einfache Zusammenlegen eines anderen Datenwerkes,
das nicht auf der Bibliothek basiert, mit der Bibliothek oder mit 
einem auf der Bibliothek basierenden Datenwerk auf ein- und demselben 
Speicher- oder Vertriebsmedium dieses andere Datenwerk nicht in den 
Anwendungsbereich dieser Lizenz. 

@item
Sie können sich für die Anwendung der Bedingungen der gewöhnlichen 
Allgemeinen Öffentlichen GNU-Lizenz (GNU-GPL) statt dieser Lizenz 
auf eine gegebene Kopie der Bibliothek entscheiden. Um dies zu tun, 
müssen Sie alle Eintragungen, die sich auf diese Lizenz beziehen, 
ändern, so dass sie nun für die gewöhnliche GNU-GPL, Version 2, 
statt für diese Lizenz (LGPL) gelten. (Wenn eine neuere Version 
als Version 2 der gewöhnlichen GNU-GPL erschienen ist, können Sie 
diese angeben, wenn Sie das wünschen.) Nehmen Sie keine anderen 
Veränderungen in diesen Eintragungen vor. 

Wenn diese Veränderung in einer gegebenen Kopie einmal vorgenommen 
ist, dann ist sie für diese Kopie nicht mehr zurücknehmbar, und 
somit gilt dann die gewöhnliche GNU-GPL für alle nachfolgenden Kopien 
und abgeleiteten Datenwerke, die von dieser Kopie gemacht worden sind. 

Diese Option ist nützlich, wenn Sie einen Teil des Codes der Bibliothek 
in ein Programm kopieren wollen, das keine Bibliothek ist. 

@item
Sie können die Bibliothek (oder einen Teil oder eine Ableitung von ihr, 
gemäß Paragraph 2) in Objektcode-Form oder in ausführbarer Form unter 
den Bedingungen der obigen Paragraphen 1 und 2 kopieren und weitergeben, 
sofern Sie den vollständigen entsprechenden maschinenlesbaren Quelltext 
beifügen, der unter den Bedingungen der obigen Paragraphen 1 und 2 
auf einem Medium weitergegeben werden muß, das üblicherweise zum 
Austausch von Software benutzt wird.

Wenn die Weitergabe von Objektcode durch das Angebot eines Zugangs zum 
Kopienabruf von einem angegebenen Ort erfolgt, dann erfüllt das Angebot 
eines gleichwertigen Zugangs zum Kopieren des Quelltextes von demselben 
Ort die Anforderung, auch den Quelltext weiterzugeben, obwohl Dritte 
nicht verplichtet sind, den Quelltext zusammen mit dem Objektcode zu 
kopieren. 

@item
Ein Programm, das nichts von irgendeinem Teil der Bibliothek 
Abgeleitetes enthält, aber darauf ausgelegt ist, mit der Bibliothek 
zusammenzuarbeiten, indem es mit ihr compiliert oder gelinkt wird, 
nennt man ein "Datenwerk, das die Bibliothek nutzt". Solch ein 
Datenwerk, für sich allein genommen, ist kein von der Bibliothek abgelei
tetes Datenwerk und fällt daher nicht unter diese Lizenz. 

Wird jedoch ein "Datenwerk, das die Bibliothek nutzt", mit der 
Bibliothek gelinkt, so entsteht ein ausführbares Programm, dass ein 
von der Bibliothek abgeleitetes Datenwerk (weil es Teile der Bibliothek 
enthält) und kein "Datenwerk, das die Bibliothek nutzt" ist. 
Das ausführbare Programm fällt daher unter diese Lizenz. 
Paragraph 6 gibt die Bedingungen für die Weitergabe solcher 
ausführbarer Programme an. 

Wenn ein "Datenwerk, das die Bibliothek nutzt", Material aus einer 
Header-Datei verwendet, die Teil der Bibliothek ist, dann kann der 
Objektcode für das Datenwerk ein von der Bibliothek abgeleitetes 
Datenwerk sein, selbst wenn der Quelltext dies nicht ist. Ob dies 
jeweils zutrifft, ist besonders dann von Bedeutung, wenn das Datenwerk 
ohne die Bibliothek gelinkt werden kann oder wenn das Datenwerk selbst 
eine Bibliothek ist. Die genaue Grenze, von der an dies zutrifft, 
ist rechtlich nicht genau definiert. 

Wenn solch eine Objektdatei nur numerische Parameter, Daten-
struktur-Layouts und Zugriffsfunktionen sowie kleine Makros und kleine 
Inlinefunktionen (zehn Zeilen lang oder kürzer) benutzt, dann 
unterliegt die Benutzung der Objektdatei keinen Beschränkungen, ohne 
Rücksicht darauf, ob es rechtlich gesehen ein abgeleitetes Datenwerk ist. 
(Ausführbare Programme, welche diesen Objektcode plus Teile der 
Bibliothek enthalten, fallen jedoch weiterhin unter die Bestimmungen 
von Paragraph 6). 

Ansonsten können Sie, wenn das Datenwerk ein von der Bibliothek 
abgeleitetes ist, den Objektcode für das Datenwerk unter den Bedingungen 
von Paragraph 6 weitergeben. Alle ausführbaren Programme, welche 
dieses Datenwerk enthalten, fallen ebenfalls unter Paragraph 6, 
gleichgültig, ob sie direkt mit der Bibliothek selbst gelinkt sind 
oder nicht. 

@item
Als Ausnahme von den Bestimmungen der vorstehenden fünf Paragraphen 
dürfen Sie auch ein "Datenwerk, das die Bibliothek nutzt", mit der 
Bibliothek kombinieren oder linken, um ein Datenwerk zu erzeugen, 
das Teile der Bibliothek enthält, und dieses unter Bedingungen Ihrer 
eigenen Wahl weitergeben, sofern diese Bedingungen Bearbeitungen 
für den eigenen Gebrauch des Empfängers und ein Rückbilden 
("reverse engineering") zum Beheben von Mängeln solcher Bearbeitungen 
gestatten. 

Sie müssen bei jeder Kopie des Datenwerks deutlich erkennbar angeben, 
dass die Bibliothek darin genutzt wird und dass die Bibliothek und Ihre 
Benutzung durch die Lizenz abgedeckt sind. Sie müssen eine Kopie 
dieser Lizenz mitgeben. Wenn das Datenwerk bei seiner Ausführung 
Copyright-Vermerke anzeigt, müssen Sie den Copyright-Vermerk für 
die Bibliothek mit anzeigen lassen und dem Benutzer einen Hinweis 
geben, der ihn zu einer Kopie dieser Lizenz führt. Ferner müssen Sie 
eines der nachfolgend genannten fünf Dinge tun: 

@enumerate a
@item
Liefern Sie das Datenwerk zusammen mit dem vollständigen zugehörigen 
maschinenlesbaren Quelltext der Bibliothek aus, und zwar 
einschließlich jeglicher in dem Datenwerk angewandter Änderungen (wobei 
dessen Weitergabe gemäß den Bedingungen der Paragraphen 1 und 2 
erfolgen muß); und wenn das Datenwerk ein ausführbares, mit der 
Bibliothek gelinktes Programm ist, dann liefern Sie es zusammen 
mit dem vollständigen maschinenlesbaren "Datenwerk, das die 
Bibliothek nutzt, in Form von Objektcode und/oder Quelltext, so dass 
der Benutzer die Bibliothek verändern und dann erneut linken kann, 
um ein verändertes ausführbares Programm zu erzeugen, das die 
veränderte Bibliothek enthält. (Es versteht sich, dass der Benutzer, 
der die Inhalte von Definitionsdateien in der veränderten Bibliothek 
verändert, nicht notwendigerweise in der Lage sein wird, die Anwendung 
neu zu compilieren, um die veränderten Definitionen zu benutzen.) 

@item
Benutzen Sie einen geeigneten ,,shared-library-Mechanismus`` zum 
Linken mit der Bibliothek. Geeignet ist ein solcher Mechanismus, 
der erstens während der Laufzeit eine im Computersystem des Benutzers 
bereits vorhandene Kopie der Bibliothek benutzt, anstatt 
Bibliotheksfunktionen in das ausführbare Programm zu kopieren, und der zweitens 
auch mit einer veränderten Version der Bibliothek, wenn der Benutzer 
eine solche installiert, richtig funktioniert, solange die veränderte 
Version schnittstellenkompatibel mit der Version ist, mit der das 
Datenwerk erstellt wurde. 

@item
Liefern Sie das Datenwerk zusammen mit einem mindestens drei Jahre 
lang gültigen schriftlichen Angebot, demselben Benutzer die oben in 
Paragraph 6, Absatz (a) genannten Materialien zu Kosten, welche die 
reinen Weitergabekosten nicht übersteigen, zur Verfügung zu stellen. 

@item
Wenn die Weitergabe des Datenwerks dadurch erfolgt, dass die 
Möglichkeit des Abrufens einer Kopie von einem bestimmten Ort 
angeboten wird, bieten Sie gleichwertigen Zugang zum Kopieren der 
oben angegebenen Materialien von dem gleichen Ort an. 

@item
Sie vergewissern sich, dass der Benutzer bereits eine Kopie dieser 
Materialien erhalten hat oder dass Sie diesem Benutzer bereits eine 
Kopie geschickt haben. 
@end enumerate

Für ein ausführbares Programm muss die verlangte Form des 
"Datenwerks, das die Bibliothek nutzt" alle Daten und Hilfsprogramme 
mit einschließen, die man braucht, um daraus das ausführbare Programm 
zu reproduzieren. Doch gilt eine spezielle Ausnahme: Die 
weiterzugebenden Materialien brauchen nicht alles das zu enthalten, was 
normalerweise (in Quelltext-Form oder in binärer Form) mit den 
Hauptbestandteilen (Compiler, Kern usw.) des Betriebssystems, 
auf denen das ausführbare Programm läuft, weitergegeben wird, es 
sei denn, das ausführbare Programm gehört selbst zu diesem 
Hauptbestandteil. 

Es kann vorkommen, dass diese Anforderung im Widerspruch zu 
Lizenzbeschränkungen anderer, proprietärer Bibliotheken steht, die 
normalerweise nicht zum Betriebssystem gehören. Ein solcher 
Widerspruch bedeutet, dass Sie nicht gleichzeitig jene proprietären 
Bibliotheken und die vorliegende Bibliothek zusammen in einem 
ausführbaren Programm, das Sie weitergeben, verwenden dürfen. 

@item
Sie dürfen Bibliotheks-Funktionseinheiten, die ein auf der Bibliothek 
basierendes Datenwerk darstellen, zusammen mit anderen, nicht unter 
diese Lizenz fallenden Funktionseinheiten in eine einzelne Bibliothek 
einbauen und eine solche kombinierte Bibliothek weitergeben, 
vorausgesetzt, dass die gesonderte Weitergabe des auf der Bibliothek 
basierenden Datenwerks einerseits und der anderen Funktionseinheiten 
andererseits ansonsten gestattet ist, und vorausgesetzt, dass Sie 
folgende zwei Dinge tun: 

@enumerate a
@item
Geben Sie zusammen mit der kombinierten Bibliothek auch eine Kopie 
desselben auf der Bibliothek basierenden Datenwerks mit, die nicht 
mit irgendwelchen anderen Funktionseinheiten kombiniert ist. 
Dieses Datenwerk muss unter den Bedingungen der obigen Paragraphen 
weitergegeben werden. 

@item
Weisen Sie bei der kombinierten Bibliothek an prominenter Stelle 
auf die Tatsache hin, dass ein Teil davon ein auf der Bibliothek 
basierendes Datenwerk ist, und erklären Sie, wo man die mitgegebene 
unkombinierte Form desselben Datenwerks finden kann. 
@end enumerate

@item
Sie dürfen die Bibliothek nicht vervielfältigen, verändern, weiter 
lizenzieren oder verbreiten oder mit ihr linken, sofern es nicht durch 
diese Lizenz ausdrücklich gestattet ist. Jeder anderweitige Versuch 
der Vervielfältigung, Modifizierung, Weiterlizenzierung und 
Verbreitung sowie des Linkens mit der Bibliothek ist unzulässig und 
beendet automatisch Ihre Rechte unter dieser Lizenz. Doch werden 
die Lizenzen Dritter, die von Ihnen Kopien oder Rechte unter dieser 
Lizenz erhalten haben, nicht beendet, solange diese Dritten die Lizenz 
voll anerkennen und befolgen. 

@item
Sie sind nicht verpflichtet, diese Lizenz anzunehmen, da Sie diese 
nicht unterzeichnet haben. Doch gibt Ihnen sonst nichts die Erlaubnis, 
die Bibliothek oder von ihr abgeleitete Datenwerke zu verändern oder 
zu verbreiten. Diese Handlungen sind gesetzlich verboten, wenn Sie 
diese Lizenz nicht annehmen. Indem Sie die Bibliothek (oder ein darauf 
basierendes Datenwerk) verändern oder verbreiten, erklären Sie Ihr 
Einverständnis mit dieser Lizenz, die Ihnen das erlaubt, mit allen 
Ihren Bedingungen bezüglich der Vervielfältigung, Verbreitung und 
Veränderung der Bibliothek oder eines darauf basierenden Datenwerks. 

@item
Jedesmal, wenn Sie die Bibliothek (oder irgendein auf der Bibliothek 
basierendes Datenwerk) weitergeben, erhält der Empfänger automatisch 
vom ursprünglichen Lizenzgeber die Lizenz, die Bibliothek entsprechend 
den hier festgelegten Bestimmungen zu vervielfältigen, zu verbreiten 
und zu verändern und mit ihr zu linken. Sie dürfen keine weiteren 
Einschränkungen der Ausübung der hierin zugestandenen Rechte des 
Empfängers vornehmen. Sie sind nicht dafür verantwortlich, die 
Einhaltung dieser Lizenz durch Dritte durchzusetzen. 

@item
Sollten Ihnen infolge eines Gerichtsurteils, des Vorwurfs einer 
Patentverletzung oder aus einem anderen Grunde (nicht auf 
Patentfragen begrenzt) Bedingungen (durch Gerichtsbeschluss, 
Vergleich oder anderweitig) auferlegt werden, die den Bedingungen 
dieser Lizenz widersprechen, so befreien diese Umstände Sie nicht 
von den Bestimmungen dieser Lizenz. Wenn es Ihnen nicht möglich ist, 
die Bibliothek unter gleichzeitiger Beachtung der Bedingungen in 
dieser Lizenz und Ihrer anderweitigen Verpflichtungen zu verbreiten, 
dann dürfen Sie als Folge davon die Bibliothek überhaupt nicht 
verbreiten. Wenn zum Beispiel ein Patent nicht die gebührenfreie 
Weiterverbreitung der Bibliothek durch diejenigen erlaubt, welche 
die Bibliothek direkt oder indirekt von Ihnen erhalten haben, dann 
besteht der einzige Weg, sowohl dem Patentrecht als auch dieser 
Lizenz zu genügen, darin, ganz auf die Verbreitung der Bibliothek 
zu verzichten. 

Sollte sich ein Teil dieses Paragraphen als ungültig oder unter 
bestimmten Umständen nicht durchsetzbar erweisen, so soll dieser 
Paragraph seinem Sinne nach angewandt werden; im übrigen soll 
dieser Paragraph als Ganzes gelten. 

Zweck dieses Paragraphen ist nicht, Sie dazu zu bringen, irgendwelche 
Patente oder andere Eigentumsansprüche zu verletzen oder die Gültigkeit 
solcher Ansprüche zu bestreiten; dieser Paragraph hat vielmehr einzig 
den Zweck, die Integrität des Verbreitungssystems der freien Software 
zu schützen, das durch die Praxis öffentlicher Lizenzen verwirklicht 
wird. Viele Leute haben großzügige Beiträge zu dem weitreichenden 
Angebot der durch dieses System verbreiteten Software im Vertrauen 
auf die konsistente Anwendung dieses Systems geleistet; es obliegt 
dem Autor bzw. Geber, zu entscheiden, ob er die Software mittels 
irgendeines anderen Systems verbreiten will; ein Lizenznehmer jedoch 
darf darüber nicht entscheiden. 

Dieser Paragraph ist dazu gedacht, deutlich klarzustellen, was als 
Konsequenz aus den übrigen Bestimmungen dieser Lizenz zu betrachten 
ist. 

@item
Wenn die Verbreitung und/oder die Benutzung der Bibliothek in 
bestimmten Staaten entweder durch Patente oder durch urheberrechtlich 
geschützte Schnittstellen eingeschränkt ist, kann der 
Urheberrechtsinhaber, der die Bibliothek unter diese Lizenz gestellt 
hat, eine explizite geographische Beschränkung der Verbreitung angeben, 
in der diese Staaten ausgeschlossen werden, so dass die Verbreitung nur 
innerhalb und zwischen den Staaten erlaubt ist, die nicht demgemäß 
ausgeschlossen sind. In einem solchen Fall beinhaltet diese Lizenz 
die Beschränkung, als wäre sie in diesem Text niedergeschrieben. 

@item
Die Free Software Foundation kann von Zeit zu Zeit überarbeitete 
und/oder neue Versionen der Lesser General Public License 
veröffentlichen. Solche neuen Versionen werden vom Grundprinzip her 
der gegenwärtigen entsprechen, können aber im Detail abweichen, um 
neuen Problemen und Anforderungen gerecht zu werden. 

Jede Version dieser Lizenz hat eine eindeutige Versionsnummer. 
Wenn in einem Programm angegeben wird, dass es dieser Lizenz in einer 
bestimmten Versionsnummer oder "jeder späteren Version" ("any later 
version") unterliegt, so haben Sie die Wahl, entweder den Bestimmungen 
der genannten Version zu folgen oder denen jeder beliebigen späteren 
Version, die von der Free Software Foundation veröffentlicht wurde. 
Wenn die Bibliothek keine Lizenz-Versionsnummer angibt, können Sie 
eine beliebige Version wählen, die jemals von der Free Software 
Foundation veröffentlicht wurde. 

@item
Wenn Sie den Wunsch haben, Teile der Bibliothek in anderen 
freien Programmen zu verwenden, deren Bedingungen für die Verbreitung 
anders sind, schreiben Sie an den Autor der Bibliothek, um ihn um die 
Erlaubnis zu bitten. Für Software, die unter dem Copyright der Free 
Software Foundation steht, schreiben Sie an die Free Software 
Foundation; wir machen zu diesem Zweck gelegentlich Ausnahmen. 
Unsere Entscheidung wird von den beiden Zielen geleitet werden, 
zum einen den freien Status aller von unserer freien Software 
abgeleiteten Datenwerke zu erhalten und zum anderen das 
gemeinschaftliche Nutzen und Wiederverwenden von Software im 
allgemeinen zu fördern. 

@iftex
@heading Keine Gewährleistung 
@end iftex
@ifinfo
@center Keine Gewährleistung 
@end ifinfo

@item
Da die Bibliothek ohne jegliche Gebühren lizenziert wird, besteht 
keinerlei Gewährleistung für die Bibliothek, soweit dies gesetzlich 
zulässig ist. Sofern nicht anderweitig schriftlich bestätigt, stellen 
die Copyright-Inhaber und/oder Dritte die Bibliothek "so, wie sie ist"
zur Verfügung, ohne Gewährleistung irgendeiner Art, weder ausdrücklich 
noch implizit. Dieser Garantieausschluss gilt auch - ohne darauf 
beschränkt zu sein - für Marktreife oder Verwendbarkeit für einen 
bestimmten Zweck. Das volle Risiko bezüglich Qualität und Leistungs-
fähigkeit der Bibliothek liegt bei Ihnen. Sollte sich die Bibliothek 
als fehlerhaft herausstellen, liegen die Kosten für notwendigen 
Service, Reparatur oder Korrektur sämtlich bei Ihnen. 

@item
In keinem Fall, außer wenn dies durch geltendes Recht gefordert 
wird oder schriftlich zugesichert wurde, ist irgendein 
Copyright-Inhaber oder irgendein Dritter, der die Bibliothek wie oben 
erlaubt modifiziert oder verbreitet hat, Ihnen gegenüber für 
irgendwelche Schäden haftbar. Dies gilt auch für jegliche allgemeine 
oder spezielle Schäden, für Schäden durch Nebenwirkungen oder 
Folgeschäden, die sich aus der Benutzung oder der Unbenutzbarkeit 
der Bibliothek ergeben (das gilt insbesondere - ohne darauf 
beschränkt zu sein - für Datenverluste, das Hineinbringen von 
Ungenauigkeiten in irgendwelche Daten, für Verluste, die Sie oder 
Dritte erlitten haben oder für ein Unvermögen der Bibliothek, 
mit irgendeiner anderen Software zusammenzuarbeiten), und zwar 
auch dann, wenn ein Copyright-Inhaber oder ein Dritter über die 
Möglichkeit solcher Schäden informiert worden ist. 

@end enumerate

@iftex
@heading Ende der Bedingungen 
@end iftex
@ifinfo
@center Ende der Bedingungen 
@end ifinfo

@appendixsec Anhang: Wie Sie diese Bedingungen auf Ihre eigenen, neuen Bibliotheken anwenden können 

Wenn Sie eine neue Bibliothek entwickeln und wünschen, dass sie 
von größtmöglichem Nutzen für die Allgemeinheit ist, dann empfehlen 
wir Ihnen, sie zu einer freien Software zu machen, die jedermann 
weiterverteilen und verändern kann. Dies können sie tun, indem Sie 
eine Weiterverteilung unter den Bedingungen dieser Lizenz, also 
der Lesser GPL erlauben (oder - als Alternative - unter den Bedingungen 
der gewöhnlichen Allgemeinen Öffentlichen GNU-Lizenz, der GPL). 

Zur Anwendung dieser Bedingungen fügen Sie zu der Bibliothek die 
unten angegebenen Vermerke hinzu. Es ist am sichersten, sie an 
den Start jeder Quelldatei anzufügen, um so am wirksamsten den 
Garantieausschluß bekannt zu machen; zumindest aber sollte jede 
Datei die Copyright-Zeile und eine Angabe enthalten, wo die 
vollständigen Vermerke zu finden sind. 



@smallexample
@var{eine Zeile mit dem Namen der Bibliothek und einer kurzen 
Beschreibung Ihres Zwecks}
Copyright (C) @var{yyyy}  @var{Name des Autors}

This library is free software; you can redistribute it and/or 
modify it under the terms of the GNU Lesser General Public License 
as published by the Free Software Foundation; either version 2.1 
of the License oder (at your option) any later version. 

This library is distributed in the hope that it will be useful, 
but ohne ANY WARRANTY; ohne even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU Lesser General Public License for more details. 

You should have received a copy of the GNU Lesser General 
Public License along with this library; if not, write to the 

Free Software Foundation, Inc., 
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 

Auf Deutsch: 

Bibliothek ist freie Software; Sie dürfen sie unter den Bedingungen 
der GNU Lesser General Public License, wie von der Free Software 
Foundation veröffentlicht, weiterverteilen und/oder modifizieren; 
entweder gemäß Version 2.1 der Lizenz oder (nach Ihrer Option) 
jeder späteren Version. 

Diese Bibliothek wird in der Hoffnung weiterverbreitet, dass sie 
nützlich sein wird, jedoch OHNE IRGENDEINE GARANTIE, auch ohne 
die implizierte Garantie der MARKTREIFE oder der VERWENDBARKEIT 
FÜR EINEN BESTIMMTEN ZWECK. Mehr Details finden Sie in der 
GNU Lesser General Public License. 

Sie sollten eine Kopie der GNU Lesser General Public License 
zusammen mit dieser Bibliothek erhalten haben; falls nicht, 
schreiben Sie an die 
Free Software Foundation, Inc., 
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 
@end smallexample

Fügen Sie auch einen kurzen Hinweis hinzu, wie Sie elektronisch 
und per Brief erreichbar sind. 

@smallexample
Soweit vorhanden, sollten Sie auch Ihren Arbeitgeber 
(wenn Sie als Programmierer arbeiten) oder Ihre Schule einen 
Copyright-Verzicht für die Bibliothek unterschreiben lassen. 
Hier ein Beispiel. Die Namen müssen Sie natürlich ändern. 

Yoyodyne, Inc., hereby disclaims all copyright interest 
in the library "Frob" (a library for tweaking knobs) 
written by James Random Hacker. 


Unterschrift von Ty Coon , 1 April 1990 
Ty Coon, President of Vice 

Auf Deutsch: 

DIe Yoyodyne GmbH erhebt keinen urheberechtlichen Anspruch 
auf die von James Random Hacker geschriebene Bibliothek "Frob" 
(eine Bibliothek für das Zwicken von Knöpfen). 


Unterschrift von Ty Coon, 1. April 1990 
Ty Coon, Vizepräsident 
@end smallexample

Das war schon alles! 



@c German FIX this node entry and section header were missing!
@c I made a guess as to what the German section title should be like ;-)
@node Function Index, Concept Index, LGPL license, Top
@c German node Function Index
@unnumbered SQL Command, Typ und Funktion Index

@printindex fn

@page


@node Concept Index,  , Function Index, Top
@c German node Concept Index
@unnumbered Concept Index

@printindex cp





@bye