我认为最自然的事情是为卡片创建一个表格,为一副牌中的每张卡片创建一个记录,然后为手牌创建一个记录,为手中的每张卡片创建一个记录。如果有关于整手牌的数据——玩家的名字?他坐在桌边的哪个位置?他有多少筹码?不管怎样——那么你需要一张单独的桌子来存放手牌,而不是手中的牌。我还会为西装创建一个查找表。
(我们可以在这里讨论合成键与自然键的使用,但这是另一个主题。)
card (cardid, suitid, rank)
suit (suitid, suitname)
hand (handid, playername, whatever)
handcard (handcardid, handid, cardid)
我的第一个冲动是让“排名”一个从 1 到 13 的数字,并在输出时将 1 转换为“Ace”,将 11 转换为 13 为“Jack”、“Queen”和“King”。您可以将它们存储为文本,但是如果有需要的话,很难比较排名。即确定13>10 对数据库来说是否容易;King>10,没那么多。
我绝对不会尝试将多个卡片的标识塞进一个字段中,无论是用句点分隔还是固定长度的 ID 或其他什么分隔。这样做需要你的程序有代码来分离这个字段以获得你想要的数据,而不是让数据库检索你想要的数据,这就是数据库的用途。
我不知道你想用这些牌手做什么,但是你可能想做的大多数事情都非常容易,就像我描述的那样场地。比如,“谁有黑桃王?” 简单的:
select playername
from hand
join handcard using (handid)
join card using (cardid)
join suit using (suitid)
where suit.name='Spades' and card.rank=13
或者,“每个玩家有多少张面孔卡?”
select playername, count(*)
from hand
join handcard using (handid)
join card using (cardid)
where card.rank between 11 and 13
当然是“玩家#3 有什么牌?” 也很容易:
select rank, suitname
from handcard
join card using (cardid)
join suit using (suitid)
where handid=3
使用打包格式执行这些查询将需要棘手的字符串提取调用。字符串操作总是很痛苦。就像您总是遇到问题一样,如果我在文本中搜索 2,我如何排除属于 '12' 的 2?等等