質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Q&A

2回答

1937閲覧

データベースのURLカラムについて、文字の型やインデックスの設定は何がいいでしょうか。

mossbarger

総合スコア26

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

0グッド

0クリップ

投稿2020/06/23 19:31

###実現したいこと

お世話になっております。
データベースにURLを入れるカラムを設けているのですが、次のエラーへの適切な対処を知りたいです。
宜しくお願いいたします。

###発生している問題・エラーメッセージ
以下エラーで、つまりCREATEVARCHAR(500)が長すぎるためにUNIQUEが使えないようです。

Specified key was too long; max key length is 767 bytes

###該当のソースコード
こちらのCREATEで生じるエラーでして、UNIQUEが原因と思います。

SQL

1CREATE TABLE IF NOT EXISTS urls ( 2 ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 3 post_ID BIGINT(20) UNSIGNED, 4 url VARCHAR(500) NOT NULL UNIQUE, 5 PRIMARY KEY (ID) 6) ENGINE=InnoDB DEFAULT CHARSET=utf8

###試したこと
解決策を2つ考えているのですが、経験不足ゆえ何が適切か見極められません。

例えばUNIQUEをやめて通常のインデックスにする解決策があるかと思います。

sql

1CREATE TABLE IF NOT EXISTS urls ( 2 ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 3 post_ID BIGINT(20) UNSIGNED, 4 # url VARCHAR(500) NOT NULL, # UNIUQEをやめる 5 INDEX index_urls_01(url), # 代わりにインデックスを貼る 6 PRIMARY KEY (ID) 7) ENGINE=InnoDB DEFAULT CHARSET=utf8

もしくはUNIQUEのままで、文字コードをlatin1へと変更する解決策です。

sql

1CREATE TABLE IF NOT EXISTS urls ( 2 ID BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT, 3 post_ID BIGINT(20) UNSIGNED, 4 url VARCHAR(500) NOT NULL UNIQUE, 5 PRIMARY KEY (ID) 6) ENGINE=InnoDB DEFAULT CHARSET=latin1 # 文字コードを変更

上記いずれかが適切と思われますか?
もしくは、もっと適切な方法等ございましたらご教示いただけませんでしょうか。
尚、urlカラムは世界にあるすべてが入りえます。

・URLは一般的には最大で約2000文字くらいまで可能なことを考えますと、そもそもUNIQUEは不適切でしょうか?

・それとも、データベースにURLを入れる際は、エンコードされた文字列よりも日本語で入っていた方がいいでしょうか。そうならばlatin1は不適切でしょうか?

・これらを考えますとインデックスが適切でしょうか。しかしurlカラムの値は重複しません(同じURLならINSERTしない)から、UNIQUEでないと不適切でしょうか?

…のように経験不足で生じうる問題などを想定する力量に欠けておりまして、ご経験豊富な皆様からお力添え頂きたい所存です。
どうぞ宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2020/06/23 20:39

用途はなんでしょう。 どういう形で取得された情報が格納されるのでしょう
mossbarger

2020/06/23 20:44

失礼いたしました。 こちらのコメントフォーム同様で、以下のようなコメントの入力例をイメージしていただければと思います。 (コメントの入力例) このページは勉強になります。 http://examle.com これをユーザーに投稿された際、URL部分を抽出してテーブルに保存しておきたいという用途です。
m.ts10806

2020/06/23 20:47

コメントということはtextareaの任意入力になると思うのですけど、 URLを別個に抽出して何に使うのでしょうか(そこを「用途は?」と問うています)
mossbarger

2020/06/23 20:51

ツイッターのカードのような埋め込みを考えています。 またはEmbedlyというサービス( 参考 → https://noripon.blog/2016/05/17/embedly/ )のような機能です。 これらの機能において同じURLをデータベースに保存するのは無駄だと考えているので、URLを一意にしたく、しかしUNIQUEが使えず苦慮している次第です。
m.ts10806

2020/06/23 21:00

そういえばURLって「全て」なら日本語ドメイン(他にも全角のURLありそうですが)も入る想定ですよね? となるとあまりユニークにすべきではないかもしれません。 ドメインやURLって「住所」で、確かに全く同じ住所ってない(はず)ですが、住所にユニークって貼りません。「どう検索させたいか」によるかもしれませんが。。
guest

回答2

0

もしくは、もっと適切な方法等ございましたらご教示いただけませんでしょうか。

MySQLのバージョンやデータベースエンジンによっては、インデックスの長さ制限が767バイトより緩和されていますので、その設定を行う方法もあります(参考)。

投稿2020/06/23 22:14

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/06/24 02:58 編集

> これをユーザーに投稿された際、URL部分を抽出してテーブルに保存しておきたいという用途です。 でしたら、そもそもUNIQUEをかけること自体が不適当にも思えます(他の投稿で同じURLを入れることができない、ということになってしまいます)。
guest

0

以下参考
MySQLのインデックスサイズに767byteまでしかつかえない問題と対策

解決方法
その1. データベースのキャラクターセットをUTF-8にする。

その2. varcharの最大長を191バイトにする
767 ÷ 4 = 191.75 の、191バイトにします。

投稿2020/06/24 02:55

編集2020/06/24 02:56
sazi

総合スコア25188

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問