2013-04-21 14 views
0

我正在开发一个类似调查的应用程序。对于选择题,我想将一个项目的组合存储在一个数字中,以将其存储在一行中。是否有算法将数字组合转换为一个数字?

因此,对于问题的数据库结构是这样的:

id type     text      item_id 
-- --------------- ---------------------------  ------- 
1 multiple_choice which one would you choose?  42 
1 multiple_choice which one would you choose?  43 
1 multiple_choice which one would you choose?  46 

这是3个选择的问题时,选择从另一个表项目被称为是id的42,43,46

所以我希望把这个组合成一个数来实现这一点:

id type     text      items 
-- --------------- ---------------------------  ------- 
1 multiple_choice which one would you choose?  x* 
  • X应该是一个数字,表示它是从数字衍生42,43,46

所以数学会是这样的

f({42,43,46}) = x and f^-1(x)={42,43,46} 

一种方法来解决这个可能是使用素数作为项目ID的。所以他们的乘法是独一无二的,但有没有办法与所有数字做到这一点?

在此先感谢。

+0

是你的ID有最大值?在这种情况下,你可以连接它们,例如它是99: 42 + 43 * 100 + 46 * 10000 ... 为什么一个数字?你为什么不做一个字符串?逗号分隔例如? – charly 2013-04-21 16:12:41

+0

@charly将它们存储在逗号分隔的字符串中是个不错的主意。但是我早些时候尝试过,当我想修改一个集合中的一个成员时(即将问题的添加/删除选项),它真的成为PHP头疼的问题。所以我真的更喜欢将这个集合保存为尽可能紧凑。即使使用'implode(,)'和'explode(,)'' – void 2013-04-21 16:14:44

+0

? – charly 2013-04-21 16:15:59

回答

1

不,不,不。这不是您想要在关系数据库中执行的操作。

您原来的questions表更接近正确的方法。

如果你想获得所有可能的答案,只是做了以下查询:

select id, type, text, group_concat(item_id) 
from questions q 
group by id, type, text; 

但是,你真的应该有两个表(至少)。问题,其中列出每个问题,并具有诸如列:

  • question_id
  • 类型
  • 文本

随着每个问题行(即,question_id是主键)。

而第二个表question_items,与像列:

  • question_items_id
  • question_id有关项目

使用此格式

  • 更多信息,上面的查询会更喜欢:

    select q.question_id, q.type, q.text, group_concat(qi.question_item_id) 
    from questions q join 
        question_items qi 
        on q.question_id = qi.question_id 
    group by q.question_id, q.type, q.text; 
    

    尽管查询看起来可能更复杂一些,但底层数据结构可以更好地表示您的问题域。这使得整个系统更加健壮和可维护。

  • +0

    谢谢,戈登!我明白你在说什么。这被称为“标准化方法”,对吗?但我懒得这样做:)并且真的试图找到一种方法来将问题存储在一张表中,如果可能的话。 – void 2013-04-21 16:17:28

    +1

    @void。 。 。是的,这是一种标准化的方法。如果你真的想这样做,那么将这些项目存储为一个逗号分隔的列表。并且,搜索有关解析逗号分隔列表的所有问题。第一次做正确的事(或者至少是“正确的”)对懒惰的人来说是真正的做法。它可以避免大量问题,简化整个开发过程。 – 2013-04-21 16:31:50

    1

    这不是最好的解决方法。而应该有多个表的结构,即

    • 问题每题= 1列,含
    • 物品每件 = 1行的文本和问题类型
    • QuestionHasItems = 1每件商品每行

    这些名称只是作为例证。沿着你已经开始的路线走下去,字段“type”,“id”和“text”是多余的,非常浪费/低效。

    如果您检查此示例,那么您将看到预填充的表结构和示例查询。 http://sqlfiddle.com/#!2/fdf5f/4

    的查询,如下所示,然后将产生的数据,你想

    SELECT 
    
        q.questionid, 
        q.questiontype, 
        q.questiontext, 
        GROUP_CONCAT(i.itemid) AS itemIDs, 
        GROUP_CONCAT(i.itemtext) AS itemTexts 
    
    FROM questions q 
    
    INNER JOIN questionHasItems qhi 
    ON qhi.questionid = q.questionid 
    
    INNER JOIN items i 
    ON i.itemid = qhi.itemid 
    
    GROUP BY q.questionid; 
    

    ,同时还可以有效地获得,例如,提供给问题的选项做的查询,如

    SELECT 
    
        i.itemid AS itemIDs, 
        i.itemtext AS itemTexts 
    
    FROM questionHasItems qhi 
    
    INNER JOIN items i 
    ON i.itemid = qhi.itemid 
    
    WHERE qhi.questionid = 1; 
    
    +0

    谢谢!但我不喜欢有额外的桌子的想法。我真的想在一张桌子上存储问题。但是如果我找不到方法,这就是我会做的。感谢您的回答。 – void 2013-04-21 16:20:00

    +0

    这样做是一个非常糟糕的设计选择。它违背了哪些数据库进行了优化。如果更新被中断或没有正确完成,它将是无用的,浪费的,并且容易出现不一致。 – 2013-04-21 16:21:03

    +0

    好的。谢谢你的帮助 :) – void 2013-04-21 16:28:56

    相关问题