我正在创建一个Android应用来存储纸牌游戏的数据,并且我想保存每个比赛数据(玩家资料ID和玩家分数)。我为此使用SQLite数据库。 我想起诉这些数据以回顾较旧的比赛,或者只是加载未完成的比赛。
当前,我将每个匹配数据存储在单独的表中,表名称为当前日期。我将4个玩家ID存储为整数,将4个玩家分数存储为字节数组(每轮得分)。
我当时想我可以将这些数据存储在单个表中,如下所示: 比赛日期的一列,球员ID的第4列为整数,球员得分的第4列为字节数组。
或者像这样: 比赛日期栏,球员ID栏组合为字符串,球员比分栏组合为字符串。
或者像这样: 比赛日期栏,球员ID和分数栏以字符串组合
答案 0 :(得分:2)
通常,您将有一个表存储“比赛”,而另一个相关表存储每个得分。它们不会“组合为字符串”。
但是,这实际上取决于您:如果您的应用程序始终总是一次只想要分数,并且您不打算针对它们查询,可以那样做。
但是,您已经正确地猜到了,您不想拥有“每场比赛一张桌子”。
答案 1 :(得分:1)
它将变得像您想要的那样复杂。考虑一下您想问数据库什么样的问题。我开始回答一个非常棘手的问题,这将涉及对提议的架构进行另一个重大更改,或者涉及子查询的更复杂的查询,或者可能只是我不太熟悉的SQL函数。我需要做更多的研究。
如果可以的话,我通常也可以弄清楚这些东西,但是我不是数据库专家,所以对我来说这绝非易事。我以为我对数据库的了解还不错,直到我对这个笑话了如指掌。
希望我没让您感到困惑。我认真考虑过要删除答案,但是我一直都投入其中。我给你一个不好的答案。但是我仍然希望它会有所帮助。
因此,我着手帮助并回答您的问题,然后我开始对此感到很开心,然后我意识到自己已不知所措。因此,请轻易接受我冗长的答案,并且对于您当前的知识和技能水平,请不要过于复杂。
就数据库基础而言,您尝试做的事情很简单,但是在您掌握数据库之前,我了解数据库可能是压倒性和困难的。。继续阅读,您会明白我为什么要这么做。如果您坚持最终成绩,那就不会太复杂。如果您想从停下来的地方重新加载游戏,它可能会变得非常复杂。
在代码中,可以执行相同操作的方法有很多,很少有“正确”的答案。无论如何,我会评论您建议的方法。
您有一个纸牌游戏,您在数据库中将其表示为match_date
,player_profile_id
和player_score
。每场比赛有四名球员。而且您想查看或加载旧的比赛以继续进行。
我将每个匹配数据存储在单独的表中,并带有当前日期的表名。我将4个玩家ID存储为整数,将4个玩家分数存储为字节数组(每轮得分)。
至少可以说,每场比赛都有一个单独的桌子很笨拙。
我当时想我可以将这些数据存储在一个表格中,例如:比赛日期列,4个玩家ID列为int,4个玩家分数列为字节数组。
好。切换到单个表是一个巨大的进步,但是数据仍然以无法查询的格式进行压缩,并且每个播放器具有不同的列不一定是理想的,但是它将满足当前的任务。
一列比赛日期,一列球员ID组合为字符串,一列球员比分组合为字符串。
我喜欢您要浓缩桌子而没有那么宽的东西。但是以这种方式压缩数据几乎无法达到数据库的目的。您将无法查询特定信息,并且可能会失去性能,因为您的Android代码(Kotlin,对吗?)必须解压缩数据。但是我没有基准来证明这一点。
一列比赛日期,一列球员ID和分数以字符串形式组合
与上一个一样,它再次将数据库与Android代码紧密耦合。数据库应执行数据库工作,而Android代码应执行Android工作。我的意思是您的数据库应该是可移植的,没有复杂的逻辑来提取所需的信息。查询应提取您需要的信息。
您正在考虑以不同的方式来做事情是件好事,这听起来像您有一个正在解决此问题的解决方案。但是,您可能会遇到的麻烦越来越大。我现在要添加很多数据库内容,因为您现在不需要实现。有时候最好做些自己拥有的技能,以便可以完成当前的任务。有时最好做一些您不知道该怎么做的复杂事情,以便可以学习。这取决于您的情况。
所以。我们将有round
和player
和match
。
round
表:
id | match_id | player_id | round_number | hand /*at the start of the round*/
87 | 3 | 96 | 0 | ["ace of spades", "kind of hearts", "7 of clubs"]
99 | 3 | 85 | 3 | [...]
以此类推
然后,您的玩家表中将包含名称,ID等列。您的比赛表将包含比赛日期,比赛ID和其他任何比赛数据
hand
打开包装它也是自己的桌子。 camelCase
列名,而不是under_score
列名。但是我认为under_score
更常用于数据库。我没有什么可以支持的。UUID
s是一回事。我还没有亲自开始使用它们,并且对于您的用例来说似乎没有必要。 我想回答一个问题:“在第7轮中有多少场比赛,而任何球员手中都有一张红桃A,没有球员拥有2家具乐部,并且没有国王留在甲板上?” < / p>
deck_start
表具有以下列:matchId
,cardName
,cardFace
,'index'
match
表具有以下列:id
,name
,date
,type
(如果匹配类型不同)card_in_hand
表具有以下列:id
,matchId
,playerId
,roundNumber
,cardName
,cardFace
所以回答这个问题
在第7轮中有多少场比赛的任何玩家都拥有一张红桃A?
没有玩家拥有两家具乐部,甲板上没有国王?
SELECT COUNT(DISTINCT match.id) FROM match
JOIN card_in_hand ON match.id = card_in_hand.matchId
WHERE card_in_hand.roundNumber = 7
AND card_in_hand.cardName LIKE 'ace'
AND card_in_hand.cardFace LIKE 'heart'
或者类似的东西。我触及了问题的第二部分……我思考得越多,问题就越复杂。您要么必须跟踪每个回合中的整个牌组,要么要使用手头上不同纸牌的数量来计算牌组索引。或者,您可以跟踪起跑阶段,然后跟踪每场比赛。真的,那可能就是那个。如果您跟踪每一个游戏。
play
表可能包含id
,matchId
,playerId
,roundNumber
,sequenceNumber
,action
然后您可能会有一个action
表,或者另外展开action
。
您可能还希望将id
表中的match
列保留为matchId
,而不仅仅是id
。如果您开始进行联接并希望获得正确的ID(匹配v来回v播放v进行任何匹配),那么最好将其作为table.tableId而不是table.id
答案 2 :(得分:1)
我会尽力用这个回答您的问题。
我当时想我可以将这些数据存储在一个表格中,例如:比赛日期列,4个玩家ID列为int,4个玩家分数列为字节数组。
我认为这是最接近的。但是我认为可以扩展一点。我实际上不知道您正在使用什么数据,所以我不知道应该如何表示player_scores
,但是我将使用字节数组滚动。
match
表:matchId
(int),matchDate
(时间戳或日期类型)(以及其他元数据列,例如匹配项的昵称,如果不同则为类型比赛类型等)score
表:matchId
,scoreId
,playerId
,playerPosition
,score
这里,score
是字节数组。
然后查询:
SELECT score.* FROM score
JOIN match ON score.matchId = match.matchId
WHERE match.matchDate > /* start_date_for search */
AND match.matchDate < /* end_date_for_search */
然后,如果一场比赛中有四名球员,那么每场比赛你将获得四行,并且可以循环查看这些行中的球员特定数据。