【问题标题】:Designing MySql tables for syncing notifications设计用于同步通知的 MySql 表
【发布时间】:2013-06-12 07:07:20
【问题描述】:

我正在尝试设计一个通知架构,其中每个通知都有一个 UID,并且需要传递给多个用户。每个用户设备都有最新通知的本地缓存。当用户设备上线时,它总是会检查是否有任何新通知并提取所有针对该用户的通知。设备会保留其同步的最新通知的 UID,并使用该 UID 从服务器获取更新的通知。

我想知道在 MySQL 表中实现此功能以使其可扩展以供超过 50 万用户使用的最佳方式。

我有一个通知详细信息表,其中通知 UID 是自动增量主键。我需要关于用户映射表的建议(忽略外键约束)

CREATE TABLE user_notifications_mapping ( 
    user_id INT UNSIGNED NOT NULL, 
    notification_id BIGINT UNSIGNED NOT NULL,
    UNIQUE KEY (user_id, notification_id)
) ENGINE=InnoDB;

但我怀疑在进行类似查询时它是否会是最佳性能

SELECT notification_id FROM user_notifications_mapping WHERE user_id = <user-id> AND notification_id > <last-notification-uid>

【问题讨论】:

    标签: mysql database-design notifications database-schema


    【解决方案1】:

    如果表被正确索引,这种设计是非常合适的。假设只有“少量”通知将在同步时返回给给定设备,中型服务器每秒将能够处理数百个此类请求,即使表很大(数百万行)。

    现在这张桌子将变得非常巨大。但我相信一个给定的通知只需要发送到一个给定的设备一次。发送通知后,我会考虑删除(或在另一个表中存档)该表的记录。从概念上讲,此表类似于pending_notifications

    [编辑]

    鉴于新信息,此表可能会超出实际大小。你需要采取不同的方法。例如,可能有一种方法可以对通知进行分组(例如,它们属于给定类型,或者它们源自应用程序中的给定实体)。相同的概念可以应用于您的用户:也许您希望将一些通知发送给(例如)所有“客户”或“所有“管理员”。

    基本思想是在两个较小基数的实体之间建立 n-n 关系。您不会模拟“某些用户收到某些通知”的情况,而是“某些用户组收到某些类型的通知”。

    例子:

    • 通知可以是“公告”、“通知”或“警告”(通知类型)
    • 用户可以是“管理员”或“客户”(用户组)

    那么notifications_mapping 表将如下所示:

    +------------------------+ |通知映射 | +------------------------+ |通知类型 | | group_id | +------------------------+

    相应的查询可能是:

    SELECT notification_id
    FROM notifications_mapping AS map
    JOIN user ON user.group_id = map.group_id
    JOIN notifications ON notifications.type = map.notification_type
    WHERE user_id = <user-id> AND notification_id > <last-notification-uid> 
    

    【讨论】:

    • 无法删除记录,因为用户可能有多个设备在不同的时间间隔同步。让服务器知道所有设备可能是一个更复杂的基础设施。这就是为什么对于所有通知,单个用户会有很多条目。这正是我认为性能可能会受到影响的原因。
    • 感谢您提出新方法的建议。但我不确定这是否适用于我的情况,因为我无法从用户中创建特定的组。它完全由用户驱动,任何人都可以为特定通知标记任意数量的用户。这本身就是一种特殊类型的通知,不可能有子类别。另外,只是想知道基于用户 ID 的水平分区有多好。这是一个好的选择吗?
    • “任何人都可以为特定通知标记任意数量的用户”:我认为这个标记是手动的,那么对于一个给定的通知,只有相对“少量”的用户可能会被通知.现在的问题是: 1. 平均而言,对于每个通知,有多少用户会收到通知? 2. 您希望每天收到多少通知?将 1. 乘以 2. 即可得到该表中每天的新记录数。 3. 如果通知超过 6 个月,您真的不能放弃通知吗?
    • 哦,是的,分区是一个非常有效的选项。实际上,现在我开始考虑它,如果您要处理 50 万用户,您可能需要一个大型数据库基础架构来处理它。考虑集群。
    • 哦,是的,我们将有一个后端作业,它将为每个用户清理超过 500 个通知的通知和映射表。不想限制时间线,因为一些用户可能不像其他用户那样活跃,但我们可能可以假设没有人会超过 500 条通知或者可能是 1000 条通知。希望分区能很好地工作。
    猜你喜欢
    • 2016-10-10
    • 2015-06-08
    • 2019-03-14
    • 2019-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多