PHP中的奇怪排序问题,使用utf8数据的mysql

时间:2011-07-22 16:04:22

标签: mysql utf-8

我的一个数据库表有一个非常奇怪的问题。我在区域(区域A,区域B等)中分类了各种区域,当我运行查询以在下拉菜单中显示它时,我得到

  • A区 - K区
  • A区 - L区
  • A区 - M区
  • A区 - 区域N
  • A区 - 区域O
  • A区 - P区
  • A区 - A区
  • A区 - B区
  • A区 - C区
  • A区 - D区
  • ...
  • A区 - G区
  • B区 - K区
  • B区 - L区
  • B区 - M区
  • B区 - N区
  • B区 - 区域O
  • B区 - P区
  • B区 - A区
  • B区 - B区
  • B区 - C区
  • B区 - D区

由于某些奇怪的原因,区域从K-> Z显示,然后从A开始。

我的表的结构如下:CREATE TABLE区域(id int(11)NOT NULL AUTO_INCREMENT,zone varchar(20)DEFAULT NULL,area varchar(100)NOT NULL,distance float(9,2)DEFAULT NULL,PRIMARY KEY(id))ENGINE = MyISAM DEFAULT CHARSET = utf8;

我的表格中的数据是希腊语,我只做了上面的例子,你可以理解并看到问题所在。要查看实际数据(希腊语),您可以访问http://www.emanaviko.gr/lists/suburbs.php

2 个答案:

答案 0 :(得分:2)

在查询中添加ORDER BY子句:

SELECT  *
FROM    areas
ORDER BY
        zone, area

答案 1 :(得分:1)

我已将您的数据导入到表中,它似乎与您获得的内容有所不同。您的默认排序规则是什么?我的是utf8_general_ci。

请注意,即使你的西方字母,实际上也不是西方字母。例如,你的K实际上是unicode字符“GREEK CAPITAL LETTER KAPPA”。

mysql> show create table foo;

+-------+----------------------------------------------------------------------------------+
| Table | Create Table                                                                     |
+-------+----------------------------------------------------------------------------------+
| foo   | CREATE TABLE `foo` (
  `z` text,
  `a` text
) ENGINE=MyISAM DEFAULT CHARSET=utf8 |
+-------+----------------------------------------------------------------------------------+

mysql> select * from foo order by z,a collate utf8_general_ci;
+-------------+-------------------------------------------------+
| z           | a                                               |
+-------------+-------------------------------------------------+
| ΖΩΝΗ Α | Αγία Βαρβάρα                         |
| ΖΩΝΗ Α | Αγία Παρασκευή                     |
| ΖΩΝΗ Α | Αγιοι Ανάργυροι                   |
| ΖΩΝΗ Α | Αγιος Στέφανος                     |
| ΖΩΝΗ Α | Αιγάλεω                                  |
| ΖΩΝΗ Α | Ανθούσα                                  |
| ΖΩΝΗ Α | Ανοιξη                                    |
| ΖΩΝΗ Α | Ανω Λιόσια                             |
| ΖΩΝΗ Α | Αχαρνές (Μενίδι)                   |
| ΖΩΝΗ Α | Βριλήσσια                              |
| ΖΩΝΗ Α | Γαλάτσι                                  |
| ΖΩΝΗ Α | Γέρακας                                  |
| ΖΩΝΗ Α | Γλυκά Νερά                             |
| ΖΩΝΗ Α | Διόνυσος                                |
| ΖΩΝΗ Α | Δροσιά                                    |
| ΖΩΝΗ Α | Εκάλη                                      |
| ΖΩΝΗ Α | Ζεφύρι                                    |
| ΖΩΝΗ Α | Ηράκλειο                                |
| ΖΩΝΗ Α | Θρακομακεδόνες                    |
| ΖΩΝΗ Α | Ιλιον                                      |
| ΖΩΝΗ Α | Κηφισιά                                  |
| ΖΩΝΗ Α | Κρυονέρι                                |
| ΖΩΝΗ Α | Λυκόβρυση                              |
| ΖΩΝΗ Α | Μαρούσι                                  |
| ΖΩΝΗ Α | Μελίσσια                                |
| ΖΩΝΗ Α | Νέα Ερυθραία                         |
| ΖΩΝΗ Α | Παλλήνη                                  |
| ΖΩΝΗ Α | Παπάγου                                  |
| ΖΩΝΗ Α | Πεντέλη                                  |
| ΖΩΝΗ Α | Περιστέρι                              |
| ΖΩΝΗ Α | Πετρούπολη                            |
| ΖΩΝΗ Α | Πεύκη                                      |
| ΖΩΝΗ Α | Ροδόπολη                                |
| ΖΩΝΗ Α | Σταμάτα                                  |
| ΖΩΝΗ Α | Φιλοθέη                                  |
| ΖΩΝΗ Α | Χαϊδάρι                                  |
| ΖΩΝΗ Α | Χαλάνδρι                                |
| ΖΩΝΗ Α | Χαλκηδόνα                              |
| ΖΩΝΗ Α | Χολαργός                                |
| ΖΩΝΗ Α | Ψυχικό                                    |
| ΖΩΝΗ Β | Αγία Σοφία                             |
| ΖΩΝΗ Β | Αγιος Βασίλειος                   |
| ΖΩΝΗ Β | Αγιος Δημήτριος(Μπραχάμι) |
| ΖΩΝΗ Β | Αλιμος                                    |
| ΖΩΝΗ Β | Ανω Γλυφάδα                           |
| ΖΩΝΗ Β | Αργυρούπολη                          |
| ΖΩΝΗ Β | Βάρη                                        |
| ΖΩΝΗ Β | Βάρκιζα                                  |
| ΖΩΝΗ Β | Βούλα                                      |
| ΖΩΝΗ Β | Βουλιαγμένη                          |
| ΖΩΝΗ Β | Βύρωνας                                  |
| ΖΩΝΗ Β | Γλυφάδα                                  |
| ΖΩΝΗ Β | Δάφνη                                      |
| ΖΩΝΗ Β | Ελληνικό                                |
| ΖΩΝΗ Β | Ζωγράφου                                |
| ΖΩΝΗ Β | Ηλιούπολη                              |
| ΖΩΝΗ Β | Καβούρι                                  |
| ΖΩΝΗ Β | Καισαριανή                            |
| ΖΩΝΗ Β | Καλλιθέα                                |
| ΖΩΝΗ Β | Καλλίπολη                              |
| ΖΩΝΗ Β | Καμίνια                                  |
| ΖΩΝΗ Β | Καστέλα                                  |
| ΖΩΝΗ Β | Νέα Σμύρνη                             |
| ΖΩΝΗ Β | Παλαιό Φάληρο                       |
| ΖΩΝΗ Β | Υμηττός                                  |
+-------------+-------------------------------------------------+
65 rows in set (0.00 sec)

mysql> set names utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from foo order by z,a collate utf8_general_ci;
+-------------+-------------------------------------------------+
| z           | a                                               |
+-------------+-------------------------------------------------+
| ΖΩΝΗ Α | Αγία Βαρβάρα                         |
| ΖΩΝΗ Α | Αγία Παρασκευή                     |
| ΖΩΝΗ Α | Αγιοι Ανάργυροι                   |
| ΖΩΝΗ Α | Αγιος Στέφανος                     |
| ΖΩΝΗ Α | Αιγάλεω                                  |
| ΖΩΝΗ Α | Ανθούσα                                  |
| ΖΩΝΗ Α | Ανοιξη                                    |
| ΖΩΝΗ Α | Ανω Λιόσια                             |
| ΖΩΝΗ Α | Αχαρνές (Μενίδι)                   |
| ΖΩΝΗ Α | Βριλήσσια                              |
| ΖΩΝΗ Α | Γαλάτσι                                  |
| ΖΩΝΗ Α | Γέρακας                                  |
| ΖΩΝΗ Α | Γλυκά Νερά                             |
| ΖΩΝΗ Α | Διόνυσος                                |
| ΖΩΝΗ Α | Δροσιά                                    |
| ΖΩΝΗ Α | Εκάλη                                      |
| ΖΩΝΗ Α | Ζεφύρι                                    |
| ΖΩΝΗ Α | Ηράκλειο                                |
| ΖΩΝΗ Α | Θρακομακεδόνες                    |
| ΖΩΝΗ Α | Ιλιον                                      |
| ΖΩΝΗ Α | Κηφισιά                                  |
| ΖΩΝΗ Α | Κρυονέρι                                |
| ΖΩΝΗ Α | Λυκόβρυση                              |
| ΖΩΝΗ Α | Μαρούσι                                  |
| ΖΩΝΗ Α | Μελίσσια                                |
| ΖΩΝΗ Α | Νέα Ερυθραία                         |
| ΖΩΝΗ Α | Παλλήνη                                  |
| ΖΩΝΗ Α | Παπάγου                                  |
| ΖΩΝΗ Α | Πεντέλη                                  |
| ΖΩΝΗ Α | Περιστέρι                              |
| ΖΩΝΗ Α | Πετρούπολη                            |
| ΖΩΝΗ Α | Πεύκη                                      |
| ΖΩΝΗ Α | Ροδόπολη                                |
| ΖΩΝΗ Α | Σταμάτα                                  |
| ΖΩΝΗ Α | Φιλοθέη                                  |
| ΖΩΝΗ Α | Χαϊδάρι                                  |
| ΖΩΝΗ Α | Χαλάνδρι                                |
| ΖΩΝΗ Α | Χαλκηδόνα                              |
| ΖΩΝΗ Α | Χολαργός                                |
| ΖΩΝΗ Α | Ψυχικό                                    |
| ΖΩΝΗ Β | Αγία Σοφία                             |
| ΖΩΝΗ Β | Αγιος Βασίλειος                   |
| ΖΩΝΗ Β | Αγιος Δημήτριος(Μπραχάμι) |
| ΖΩΝΗ Β | Αλιμος                                    |
| ΖΩΝΗ Β | Ανω Γλυφάδα                           |
| ΖΩΝΗ Β | Αργυρούπολη                          |
| ΖΩΝΗ Β | Βάρη                                        |
| ΖΩΝΗ Β | Βάρκιζα                                  |
| ΖΩΝΗ Β | Βούλα                                      |
| ΖΩΝΗ Β | Βουλιαγμένη                          |
| ΖΩΝΗ Β | Βύρωνας                                  |
| ΖΩΝΗ Β | Γλυφάδα                                  |
| ΖΩΝΗ Β | Δάφνη                                      |
| ΖΩΝΗ Β | Ελληνικό                                |
| ΖΩΝΗ Β | Ζωγράφου                                |
| ΖΩΝΗ Β | Ηλιούπολη                              |
| ΖΩΝΗ Β | Καβούρι                                  |
| ΖΩΝΗ Β | Καισαριανή                            |
| ΖΩΝΗ Β | Καλλιθέα                                |
| ΖΩΝΗ Β | Καλλίπολη                              |
| ΖΩΝΗ Β | Καμίνια                                  |
| ΖΩΝΗ Β | Καστέλα                                  |
| ΖΩΝΗ Β | Νέα Σμύρνη                             |
| ΖΩΝΗ Β | Παλαιό Φάληρο                       |
| ΖΩΝΗ Β | Υμηττός                                  |
+-------------+-------------------------------------------------+

更新:

行。我导入了你的转储文件。

您的问题是表中包含错误的数据。它实际上是双重编码的utf8。

使用phpmyadmin查看表:你应该看到垃圾而不是文本。

你的PHP代码中可能有一个错误,你忘了发出“SET NAMES utf8”或mysql_set_charset(“utf8”)。插入时你也有同样的错误。

因此,当您发出

INSERT 'Αγία Παρασκευή'

PHP将utf-8编码数据发送给MySQL。但MySQL认为它是latin1。因此,它将它再次转换为utf8,并且您的表包含垃圾。

当您选择SELECT时,mysql会将utf8转换回latin1,但这实际上会为您提供最初发送的utf8,因此它会在您的应用程序中正确显示。

但是表的内容是垃圾,并按垃圾顺序排序;)

首先,您需要在代码中修复该错误。

然后你需要导出那些表(你提供的文件工作正常),删除它们,然后使用正确的字符集重新导入它们(在文件顶部添加一个SET NAMES utf8)。

更新2:

如果你想知道数据是不是垃圾,有一些简单的技巧:

SELECT upper(yourcolumn) (or lower()...) 
SELECT char_length(yourcolumn)

如果它有效(即,你得到正确的大写或小写文本和正确的字符长度,那么这意味着数据是好的,mysql理解它。

检查你的mysql连接是否正确配置的常用技巧是发出(在你的php代码中)这个查询:

SELECT char_length('é'), octet_length('é'), upper('é')
+-------------------+--------------------+-------------+
| char_length('é') | octet_length('é') | upper('é') |
+-------------------+--------------------+-------------+
|                 1 |                  2 | É          |
+-------------------+--------------------+-------------+

当然可以做到

SHOW VARIABLES LIKE '%character%';

我使用phpmyadmin和mysql控制台。