4

名前の一部を指定できるメンバー検索機能があり、その入力に一致するユーザー名、名、または姓の少なくとも1つを持つすべてのメンバーが返される必要があります。ここでの問題は、一部の名前にéinのような「奇妙な」文字がRenéeあり、ユーザーが奇妙な文字を入力したくないが、通常のASCII置換を使用したいということeです。

PHPでは、iconvを使用して入力文字列をASCIIに変換します(誰かが奇妙な文字を入力した場合に備えて)。ただし、データベースでは、文字列を一致させるために、奇妙な文字を(明らかに)ASCIIに変換する必要があります。

私は次のことを試しました:

SELECT
  CONVERT(_latin1'Renée' USING ascii) t1, 
  CAST(_latin1'Renée' AS CHAR CHARACTER SET ASCII) t2;

(これは2回の試行です。)どちらも機能しません。両方ともRen?e出力として持っています。疑問符は。である必要がありeます。Ren?ee変換後にすべての疑問符を削除できるので、出力されても問題ありません。

ご想像のとおり、クエリする列はLatin1でエンコードされています。

ありがとう。

4

4 に答える 4

7

何も変換する必要はありません。要件は、2 つの文字列を比較し、アクセントを無視して等しいかどうかを確認することです。データベースサーバーは照合を使用してそれを行うことができます:

非 UCA 照合には、文字コードから重みへの 1 対 1 のマッピングがあります。MySQL では、このような照合は大文字と小文字を区別せず、アクセントも区別しません。utf8_general_ci はその例です。「a」、「A」、「À」、および「á」はそれぞれ異なる文字コードを持ちますが、重みはすべて 0x0041 であり、等しいものとして比較されます。

mysql> SET NAMES 'utf8' COLLATE 'utf8_general_ci';
Query OK, 0 rows affected (0.00 sec)

mysql> SELECT 'a' = 'A', 'a' = 'À', 'a' = 'á';
+-----------+-----------+-----------+
| 'a' = 'A' | 'a' = 'À' | 'a' = 'á' |
+-----------+-----------+-----------+
|         1 |         1 |         1 |
+-----------+-----------+-----------+
1 row in set (0.06 sec)
于 2010-12-24T11:33:32.153 に答える
6

まず、次のように機能する必要があります。

SELECT * FROM `test` WHERE `name` COLLATE utf8_general_ci LIKE '%renee%';

testテーブルはどこにありますか:

+-----+--------+
| id  | name   |
+-----+--------+
|  1  | Renée  |
|  2  | Renêe  |
|  3  | Renee  |
+-----+--------+

MySQLのバージョンは何ですか?また、どのように一致させようとしますか?


他の可能な解決策の1つは音訳です。

関連:PHP音訳

入力の音訳は問題にはなりませんが、検索中に永続ストレージ(dbなど)からリアルタイムで値を音訳することはできない場合があります。したがって、、、、などの3つのフィールドを追加username_slugできfirstname_slugますlastname_slug。レコードを挿入/変更するときは、スラッグ値を適切に設定してください。そして、検索するときは、文字変換された入力をそのスラッグフィールドに対して検索します。

+------+----------+---------------+----------+---------------+ ...
| id   | username | username_slug | lastname | lastname_slug | ...
+------+----------+---------------+----------+---------------+ ...
|    1 | Renée    |    renee      | La Niña  | la-nina       | ...
|    2 | Renêe    |    renee      | ...      | ...           | ...
|    3 | Renee    |    renee      | ...      | ...           | ...
+------+----------+---------------+----------+---------------+ ...

「renee」または「renèe」を検索すると、すべてのレコードが一致します。

副作用として、そのフィールドを使用してSEF(検索エンジンに適した)リンクを生成できる場合があるため..._slug、たとえばexample.com/users/reneeなどの名前が付けられます。もちろん、その場合は、スラッグフィールドの一意性を確認する必要があります。

于 2010-12-26T14:11:05.113 に答える
3

文字エンコーディングのコンテキストでのCAST()演算子は、ある文字ストレージの方法から別の方法に変換します。実際の文字は変更されません。これが目的です。é 文字は、任意の文字セットで使用される文字であり、e ではありません。アクセント付きの文字をアクセントのない文字に変換する必要があります。これは別の問題であり、以前に何度も尋ねられました ( MySQL クエリでアクセント付きの文字を正規化する)。

変換テーブルを用意して文字ごとに処理する以外に、MySQL で直接これを行う方法があるかどうかはわかりません。おそらく、PHP スクリプトを作成してデータベースを調べて翻訳を行う方が簡単でしょう。

于 2010-11-20T17:51:58.213 に答える
3

上記の@vincebowdrenの回答は機能します。書式設定の目的でこれを回答として追加しています。

CREATE TABLE `members` (
  `id` int(11) DEFAULT NULL,
  `lastname` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL
);
insert into members values (1, 'test6ë');
select id from members where lastname like 'test6e%';

収量

+--------+
| | ID |
+--------+
| | 1 |
+--------+

そして、Latin1 を使用すると、

set names latin1;
CREATE TABLE `members2` (
  `id` int(11) DEFAULT NULL,
  `lastname` varchar(20) CHARACTER SET latin1 DEFAULT NULL
);
insert into members2 values (1, 'Renée');
select id from members2 where lastname like '%Renee%';

が得られます:

+--------+
| | ID |
+--------+
| | 1 |
+--------+

もちろん、OP は、アプリケーション (PHP)、接続 (Linux 上の MySQL は 5.0 ではデフォルトで latin1 でしたが、5.1 ではデフォルトで UTF8 です)、およびフィールド データ型で同じ文字セットを使用して、未知数を少なくする必要があります。残りは照合が処理します。

編集:すべてをより適切に制御する必要があると書きましたが、以下も機能します:

set names latin1;
select id from members where lastname like 'test6ë%';

接続文字セットが設定されると、MySQL は内部で変換を行うためです。この場合、UTF8文字列(DBから)をlatin1(クエリから)に変換して比較します。

編集 2:一部の懐疑論では、さらに説得力のある例を提供する必要があります。

上記のステートメントを考えると、ここで私はさらに何をしましたか。端末が UTF8 であることを確認します。

set names utf8;
insert into members values (5, 'Renée'), (6, 'Renêe'), (7, 'Renèe');
select members.id, members.lastname, members2.id, members2.lastname
from members inner join members2 using (lastname);

これmembersは utf8 でmembers2あり、latin1 であることに注意してください。

+------+----------+------+----------+
| | ID | 姓 | ID | 姓 |
+------+----------+------+----------+
| | 5 | ルネ | 1 | ルネ |
| | 6 | ルネ | 1 | ルネ |
| | 7 | ルネ | 1 | ルネ |
+------+----------+------+----------+

これは正しい設定で証明されており、照合が自動的に機能します。

于 2010-12-25T06:31:28.090 に答える