如何为聊天应用程序中的民意调查设计数据库架构?
How can I design a database schema for polls in a chat app?
我正在为一个聊天应用程序创建一个聊天机器人,人们可以 运行 一个命令并为投票指定一个问题和可能的答案,在将表情符号反应添加到作者的消息中之后,我的机器人删除添加所有反应并将投票存储在数据库中,使投票匿名,我的问题是如何设计我的模式?我正在使用 Postgres 数据库,我的想法是这样的:
// Creating a poll from those values
const question = "what is the best color?"
const answerCache = ["red", "green", "blue"]
// Helpers for mapping emoji reactions to a index
const emojis = ["emojiForFirstChoice", "emojiForSecond", "emoijForThird"]
const getIndexFromReaction = r => emojis.findIndex(e => r === e)
// Example of reaction
const authorId = "someId"
const reaction = "emojiForFirstChoice"
const index = getIndexFromReaction(reaction)
@Entity()
export class Question extends BaseEntity {
@PrimaryColumn()
messageId!: string;
@Column()
authorId!: string;
@Column()
question!: string;
@Column("string", { array: true })
answerCache!: string[];
@OneToMany(
() => Answer,
answer => answer.question
)
answers: Answer[];
}
然后我会创建一个单独的架构
@Entity()
export class Answer extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
authorId: string;
@Column()
index: number;
@ManyToOne(
() => Question,
question => question.answers,
{
onDelete: "CASCADE",
}
)
question: Question;
}
这样,每当有人添加反应时,我都会将它们存储在答案中 table,当他们更改答案时,我会更新该列的索引,当投票结束时,我会收集所有索引,由于答案存储在一个数组中,我可以使用索引计算每个答案,我看到的一些可能的问题/我有的问题:
- 这样存储原始答案(answerCache)是不是省事了? Postgres 是否保证正确的顺序?
- 我应该改为完全关联吗?如果是这样,最好的方法是什么?
- 我能否将所有这些组合成一个
Poll
实体,但仍然具有相同的行为?
您存储它的方式很好。
因为可能的答案 (answerCache
) 确实是一个数组,所以您可以这样保留它们。为他们创建一个 table 不会在这里带来任何真正的优势,除非你想做一些分析,比如“什么是最常见的答案”。
关于保持秩序,我找不到任何说它没有的东西,但我建议你先测试一下。另一种选择是将 answerCache
保存为字符串,当您需要使用数组时,使用 JSON.parse
将其转换回来
您可以将所有这些组合成一个 table,但您可能需要保存 json
或 jsonb
列以保留有关回答者的所有信息。
我正在为一个聊天应用程序创建一个聊天机器人,人们可以 运行 一个命令并为投票指定一个问题和可能的答案,在将表情符号反应添加到作者的消息中之后,我的机器人删除添加所有反应并将投票存储在数据库中,使投票匿名,我的问题是如何设计我的模式?我正在使用 Postgres 数据库,我的想法是这样的:
// Creating a poll from those values
const question = "what is the best color?"
const answerCache = ["red", "green", "blue"]
// Helpers for mapping emoji reactions to a index
const emojis = ["emojiForFirstChoice", "emojiForSecond", "emoijForThird"]
const getIndexFromReaction = r => emojis.findIndex(e => r === e)
// Example of reaction
const authorId = "someId"
const reaction = "emojiForFirstChoice"
const index = getIndexFromReaction(reaction)
@Entity()
export class Question extends BaseEntity {
@PrimaryColumn()
messageId!: string;
@Column()
authorId!: string;
@Column()
question!: string;
@Column("string", { array: true })
answerCache!: string[];
@OneToMany(
() => Answer,
answer => answer.question
)
answers: Answer[];
}
然后我会创建一个单独的架构
@Entity()
export class Answer extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column()
authorId: string;
@Column()
index: number;
@ManyToOne(
() => Question,
question => question.answers,
{
onDelete: "CASCADE",
}
)
question: Question;
}
这样,每当有人添加反应时,我都会将它们存储在答案中 table,当他们更改答案时,我会更新该列的索引,当投票结束时,我会收集所有索引,由于答案存储在一个数组中,我可以使用索引计算每个答案,我看到的一些可能的问题/我有的问题:
- 这样存储原始答案(answerCache)是不是省事了? Postgres 是否保证正确的顺序?
- 我应该改为完全关联吗?如果是这样,最好的方法是什么?
- 我能否将所有这些组合成一个
Poll
实体,但仍然具有相同的行为?
您存储它的方式很好。
因为可能的答案 (answerCache
) 确实是一个数组,所以您可以这样保留它们。为他们创建一个 table 不会在这里带来任何真正的优势,除非你想做一些分析,比如“什么是最常见的答案”。
关于保持秩序,我找不到任何说它没有的东西,但我建议你先测试一下。另一种选择是将 answerCache
保存为字符串,当您需要使用数组时,使用 JSON.parse
您可以将所有这些组合成一个 table,但您可能需要保存 json
或 jsonb
列以保留有关回答者的所有信息。