Странная проблема сортировки в PHP, mysql с данными utf8 - PullRequest
1 голос
/ 22 июля 2011

У меня очень странная проблема с одной из моих таблиц БД. У меня есть различные области, классифицированные в зонах (зона A, зона B и т. Д.), И когда я запускаю запрос для отображения их в раскрывающемся меню, я получаю

  • Зона А - Зона К
  • Зона А - Зона L
  • Зона А - Зона М
  • Зона А - Зона 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 area (id int (11) NOT NULL AUTO_INCREMENT, зона varchar (20) DEFAULT NULL, область varchar (100) NOT NULL, расстояние с плавающей точкой (9,2) DEFAULT NULL, PRIMARY КЛЮЧ (id)) ДВИГАТЕЛЬ = CHISSET ПО УМОЛЧАНИЮ MyISAM = utf8;

Данные в моей таблице приведены на греческом языке, я сделал приведенный выше пример только для того, чтобы вы могли понять и увидеть проблему. Для просмотра актуальных данных (на греческом языке) вы можете посетить http://www.emanaviko.gr/lists/suburbs.php

Ответы [ 2 ]

2 голосов
/ 22 июля 2011

Добавить ORDER BY предложение к вашему запросу:

SELECT  *
FROM    areas
ORDER BY
        zone, area
1 голос
/ 22 июля 2011

Я импортировал ваши данные в таблицу, и они, похоже, отличаются от того, что вы получаете. Каково ваше сопоставление по умолчанию? Мой utf8_general_ci.

Обратите внимание, что даже ваши западные буквы на самом деле не западные буквы. Например, ваш K на самом деле является символом юникода "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                                               |
+-------------+-------------------------------------------------+
| ΖΩΝΗ Α | Αγία Βαρβάρα                         |
| ΖΩΝΗ Α | Αγία Παρασκευή                     |
| ΖΩΝΗ Α | Αγιοι Ανάργυροι                   |
| ΖΩΝΗ Α | Αγιος Στέφανος                     |
| ΖΩΝΗ Α | Αιγάλεω                                  |
| ΖΩΝΗ Α | Ανθούσα                                  |
| ΖΩΝΗ Α | Ανοιξη                                    |
| ΖΩΝΗ Α | Ανω Λιόσια                             |
| ΖΩΝΗ Α | Αχαρνές (Μενίδι)                   |
| ΖΩΝΗ Α | Βριλήσσια                              |
| ΖΩΝΗ Α | Γαλάτσι                                  |
| ΖΩΝΗ Α | Γέρακας                                  |
| ΖΩΝΗ Α | Γλυκά Νερά                             |
| ΖΩΝΗ Α | Διόνυσος                                |
| ΖΩΝΗ Α | Δροσιά                                    |
| ΖΩΝΗ Α | Εκάλη                                      |
| ΖΩΝΗ Α | Ζεφύρι                                    |
| ΖΩΝΗ Α | Ηράκλειο                                |
| ΖΩΝΗ Α | Θρακομακεδόνες                    |
| ΖΩΝΗ Α | Ιλιον                                      |
| ΖΩΝΗ Α | Κηφισιά                                  |
| ΖΩΝΗ Α | Κρυονέρι                                |
| ΖΩΝΗ Α | Λυκόβρυση                              |
| ΖΩΝΗ Α | Μαρούσι                                  |
| ΖΩΝΗ Α | Μελίσσια                                |
| ΖΩΝΗ Α | Νέα Ερυθραία                         |
| ΖΩΝΗ Α | Παλλήνη                                  |
| ΖΩΝΗ Α | Παπάγου                                  |
| ΖΩΝΗ Α | Πεντέλη                                  |
| ΖΩΝΗ Α | Περιστέρι                              |
| ΖΩΝΗ Α | Πετρούπολη                            |
| ΖΩΝΗ Α | Πεύκη                                      |
| ΖΩΝΗ Α | Ροδόπολη                                |
| ΖΩΝΗ Α | Σταμάτα                                  |
| ΖΩΝΗ Α | Φιλοθέη                                  |
| ΖΩΝΗ Α | Χαϊδάρι                                  |
| ΖΩΝΗ Α | Χαλάνδρι                                |
| ΖΩΝΗ Α | Χαλκηδόνα                              |
| ΖΩΝΗ Α | Χολαργός                                |
| ΖΩΝΗ Α | Ψυχικό                                    |
| ΖΩΝΗ Β | Αγία Σοφία                             |
| ΖΩΝΗ Β | Αγιος Βασίλειος                   |
| ΖΩΝΗ Β | Αγιος Δημήτριος(Μπραχάμι) |
| ΖΩΝΗ Β | Αλιμος                                    |
| ΖΩΝΗ Β | Ανω Γλυφάδα                           |
| ΖΩΝΗ Β | Αργυρούπολη                          |
| ΖΩΝΗ Β | Βάρη                                        |
| ΖΩΝΗ Β | Βάρκιζα                                  |
| ΖΩΝΗ Β | Βούλα                                      |
| ΖΩΝΗ Β | Βουλιαγμένη                          |
| ΖΩΝΗ Β | Βύρωνας                                  |
| ΖΩΝΗ Β | Γλυφάδα                                  |
| ΖΩΝΗ Β | Δάφνη                                      |
| ΖΩΝΗ Β | Ελληνικό                                |
| ΖΩΝΗ Β | Ζωγράφου                                |
| ΖΩΝΗ Β | Ηλιούπολη                              |
| ΖΩΝΗ Β | Καβούρι                                  |
| ΖΩΝΗ Β | Καισαριανή                            |
| ΖΩΝΗ Β | Καλλιθέα                                |
| ΖΩΝΗ Β | Καλλίπολη                              |
| ΖΩΝΗ Β | Καμίνια                                  |
| ΖΩΝΗ Β | Καστέλα                                  |
| ΖΩΝΗ Β | Νέα Σμύρνη                             |
| ΖΩΝΗ Β | Παλαιό Φάληρο                       |
| ΖΩΝΗ Β | Υμηττός                                  |
+-------------+-------------------------------------------------+

Обновление:

OK. Я импортировал ваш файл дампа.

Ваша проблема в том, что таблицы содержат неверные данные. На самом деле это двойное кодирование utf8.

Просмотрите таблицы с помощью phpmyadmin: вы должны увидеть мусор вместо текста.

Возможно, в вашем PHP-коде есть ошибка, из-за которой вы забыли выдать SET NAMES utf8 или mysql_set_charset (utf8). И у вас была та же ошибка при вставке.

Поэтому при выдаче

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

PHP отправляет данные в кодировке utf-8 в MySQL. Но MySQL считает, что это латынь1. Таким образом, он снова преобразует его в 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...