我正在开发一个需要在数据库中存储一副手的应用程序。我不确定什么是在数据库中表示这一点的最佳方式。
该套牌将预先发给4手牌,每张牌由申请人持有13张牌。之后,我需要存储手和其他数据,如西装分发等......
最好为每只手创建一个单独的行并将其与牌组相关联吗?或者将它们保持在一排可能会更好?
此外,我不确定是否应将其保留为文字或数字。 这是一个例子:
Sorted by suit and separated by dot
AK.32.6543.AKQ98
或者
(52 = Largest rank or largest suit or 02 = 2 of smallest suit)
405251282717161514012322200908
有什么想法吗?
PS:有理由存放卡片。我们需要分析手牌分布,高卡积分等......
答案 0 :(得分:4)
这取决于您想要做的分析。如果是我,我可能默认为(忽略非主要约束)
CREATE TABLE card (
card_id NUMBER PRIMARY KEY,
suit VARCHAR2(10) NOT NULL,
value VARCHAR2(1) NOT NULL
);
CREATE TABLE hand (
hand_id NUMBER PRIMARY KEY,
player_id NUMBER NOT NULL
);
CREATE TABLE hand_element (
hand_element_id NUMBER PRIMARY KEY,
hand_id NUMBER NOT NULL,
card_id NUMBER NOT NULL
);
每个HAND
在HAND_ELEMENT
中有13行。我不打算存储关于套装分布的信息,我只是计算一只手的分布,即
SELECT suit, count(*)
FROM hand JOIN hand_element USING (hand_id)
JOIN card USING (card_id)
WHERE hand_id = :some_hand_id
答案 1 :(得分:4)
我认为最自然的事情就是为牌创建一张桌子,牌桌上的每张牌都有一张记录,然后是手牌的记录,手上的每张牌都有一张记录。如果有关于手牌整体的数据 - 球员的名字?他坐在桌旁的地方?他有多少筹码?无论如何 - 那么你需要一个单独的桌子,而不是手中的牌。我还会为西装创建一个查找表。
(我们可以在这里讨论合成键与自然键的使用,但这是另一个主题。)
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;国王> 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?等
答案 2 :(得分:0)
我也在为3张牌扑克做类似的项目。我像这样设置我的SQL:
CREATE TABLE cards
(
id int AUTO_INCREMENT,
suite varchar(30) NOT NULL,
rank int NOT NULL,
dealt BOOLEAN DEFAULT false,
PRIMARY KEY (id)
);
然后运行命令以这种方式填充数据库:
INSERT INTO cards (suite,rank) VALUES ('spades',1);
通过这种方式,您可以循环访问数据库,并在处理卡片时将更改处理为“true”。还可以轻松比较等级。