5

mysqlテーブルに3つの列で構成される主キーがあります。

CREATE TABLE IF NOT EXISTS `bb_bulletin` (
  `OfficeCode` int(5) NOT NULL,
  `IssuerId` int(11) NOT NULL,
  `BulletinDtm` datetime NOT NULL,
  `CategoryCode` varchar(4) NOT NULL,
  `Title` varchar(255) NOT NULL,
  `Content` text NOT NULL,
  PRIMARY KEY (`OfficeCode`,`IssuerId`,`BulletinDtm`),
  UNIQUE KEY `U_IssuerId` (`IssuerId`,`OfficeCode`,`BulletinDtm`),
  UNIQUE KEY `U_CategoryCode` (`CategoryCode`,`OfficeCode`,`IssuerId`,`BulletinDtm`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

主キーの特定の値のレコードを選択するための簡単な方法はありますか?

私は試した。

SELECT * FROM `bb_bulletin` WHERE PRIMARY = '20001-1-2011-01-07 14:04:40'

長い手で行う方法の代わりに、

SELECT * From bb_bulletin WHERE OfficeCode = 20001 AND IssuerId = 1 AND BulletinDtm = 2011-01-07 14:04:40

テーブルでphpキーと複合キーを処理するときの標準は何ですか。注:これを解決するために、テーブルに自動インクリメントキーを追加したくありません。それが不可能な場合は、URLで3つの制約を渡すだけです。

4

4 に答える 4

8

あなたの質問には2つの部分があります。最初の部分は、複合値の参照についてです。MySQLがこれをサポートしているかどうかはわかりませんが、これを行うためのSQL標準の方法になります。

SELECT * FROM bb_bulletin WHERE (OfficeCode, IssuerId, BulletinDtm) = (20001, 1, '2011-01-07 14:04:40');

他の部分は、省略された構文を使用して主キー列を参照しています。私はそのような可能性を知りません。

于 2011-01-25T00:10:20.663 に答える
1

いいえ、MySQLでも、私が知っているSQL方言でも、そのような方法はありません。

20001-1-2011-01-07 14:04:40PHPで文字列を分割し、その部分を使用してMySQLクエリを作成する必要があります。

また、複合主キーはパフォーマンスの面で最良のアイデアではない可能性があります(特にInnoDBテーブルの場合)

またINT(5)、それでも同じくらいのスペースがINT(11)必要です(またはそのことについてはプレーンINTです)。小さい整数型の場合は、、およびを使用TINYINTSMALLINTますMEDIUMINT


不器用な回避策のセクション

以下のソリューションは、希望どおりに機能するはずですが、リソースやパフォーマンスが犠牲になります。あなたが本当に最も単純な解決策で行くことができないのでない限り、あなたはこれらを使うべきではありません。


それを行うため の恐ろしい方法はこのようになりますWHERE CONCAT(OfficeCode,IssuerId,BulletinDtm) = '20001-1-2011-01-07 14:04:40'

MySQLがインデックスを使用して実際にクエリを高速化できないため、これは恐ろしいことです。

これをしないでください。


別の方法。テーブルに列を追加しCHAR(32)て、PKにします。以前のPK列のMD5ハッシュ(つまり、MD5( '20001-1-2011-01-07 14:04:40')を格納します。次に、次のようにクエリを実行できますWHERE newPKcolumn = MD5('20001-1-2011-01-07 14:04:40')。これにより、必要な操作を実行できます。テーブルは正規化されなくなりましたが、非正規化は、パフォーマンスや使いやすさを向上させるために時々行う必要のあるトレードオフです。これに問題はありません。

于 2011-01-24T23:40:43.903 に答える
0

(文字列)を引数として取るストアドプロシージャを作成し'20001-1-2011-01-07 14:04:40'、それを解析してSELECT、プロシージャ内にステートメントを作成することができます。

于 2011-01-24T23:43:05.570 に答える
0

そのようにすることはできません。事前解析するストアドプロシージャは、これを実行する1つの方法です。このテーブルデザインに固執する必要がない場合は、主キーを自動インクリメントに設定できる新しい列に変更することをお勧めします。

この設計に固執する必要がある場合でも、新しい「マッピング」テーブルを追加できます。これは、名前が示すように、組み合わせを主キーにマッピングします。

CREATE TABLE IF NOT EXISTS `bbb_mapping` (
  `YourPK` int(11) NOT NULL AUTO_INCREMENT,
  `OfficeCode` int(5) NOT NULL,
  `IssuerId` int(11) NOT NULL,
  `BulletinDtm` datetime NOT NULL
  PRIMARY KEY (`YourPK`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

このアプローチを使用すると、クエリ文字列でYourPKを使用しながら、マッピングテーブルを元のテーブルに結合できます。

乾杯

于 2011-01-24T23:56:14.467 に答える