登录后如何合并用户数据?

Rad*_*mko 8 database theory database-design data-structures

如果您正在构建eshop或任何其他使用会话在请求之间存储某些数据的应用程序,则无关紧要.如果您不想通过要求他注册来惹恼用户,您需要允许他在可能的情况下匿名执行某些任务(用户确实需要有注册的理由).

出现了一个问题 - 如果用户决定使用他现有的个人资料登录,他可能已经在他的"匿名"会话中拥有了一些数据.

合并这些数据的最佳做法是什么?我猜测应用程序应尽可能自动合并,或让用户决定哪里不可能.

但我要问的更多的是,是否有任何关于如何有效地在数据库(通常存储会话数据)中进行魔术的资源.

我脑子里有两个基本的解决方案:

  1. 保持匿名会话数据,并添加另一个"关系",说明实际使用的位置和方式的合并
  2. 物理合并这些数据

我们可以说第一个解决方案可能会更有效,因为任何关系的信息可能意味着数据少于用户数据.但这也意味着在读取数据时会有更多的努力(因为我们首先需要阅读关系来获取实际的用户数据).

是否有任何文章/资源来设计这个特定用例的数据结构(匿名+用户数据)?

Dmi*_*sev 9

一个很好的问题,任何使用用户数据的应用程序开发人员都应该问,而且,很遗憾很少:(

事实上,这里有两个完全独立的问题:

  • Q1 - 在什么阶段要求用户登录/注册?

  • Q2 - 数据并发和冲突解决(见下文).

这里对每个问题进行一些分析.请原谅我对自己"沮丧的用户"体验带来的额外激情.:)


Q1是纯粹的可用性问题.答案显而易见:

  • 避免或延迟强制用户尽可能登录!

即使是拯救国家的需要也不足以成为理由.如果我对用户不感兴趣保存该状态,请不要强迫我签名!请!

你(作为网站)强迫我签名的唯一原因是当我(作为用户)想要保存我的数据供以后使用时.在这里我说的是用户浪费时间签名只是为了找到网站没用.如果你想摆脱太多用户,这是正确的方法.在任何其他情况下 - 请尽可能延迟!

为什么这么多网站完全无视这么明显的规则?我可以看到的可能原因:

  • R1-开发人员友好与用户友好.是的,开发人员友好,需要立即登录,所以我们不需要打扰并发(Q2).因此,我们可以节省开发人员的成本,时间等.但每次节省都需要付出代价!在这种情况下称为用户体验.这不一定是您想要寻找储蓄的地方.特别是,因为解决方案不应该那么难(见下文).

  • R2 - 做出决定的设计师或经理是一个"室内爱好者":)她过着幸福的生活,被超高速的电脑和超快的互联网连接包围着,无法想象唱歌对任何用户来说都很难.那么为什么这么重要呢?原因很多:

  • 它打破了应用程序流程.生活在上个世纪的网站仍然以有时相当冗长的形式取代整个屏幕.有些形式的设计很糟糕,有些形式有不稳定的指示,有些则根本不起作用.有些人提交的按钮由于某些原因在使用的浏览器中被禁用.一些表单设计师有天才的想法来锁定某些字段,几乎没有明显的变化或颜色.如果你不想让我填写它,那么不要告诉我这个领域!

  • 如果网站认真对待用户的数据,它必须要求电子邮件,并且必须对其进行验证!为什么?我怎么回到忘记所有其他凭据的用户?为何验证?如果用户输错了电子邮件怎么办?如果我不验证它,下次用户尝试使用正确的电子邮件恢复密码时,恢复将失败并且所有数据都将丢失!很明显,但仍有网站没有这样做.然后我需要等到收到验证邮件并点击,希望,格式良好且唯一可识别的链接不会在我的浏览器中断,也不会因为编码检测错误而得到一些有趣的字符,使整个链接无法使用.

  • 互联网连接可能很慢或破坏,使每一个额外的步骤都成为一种痛苦.即使有良好的连接,它也会发生在那里,该页面突然需要更长的时间来加载.电子邮件也可能不会立即到达.然后不耐烦的用户开始疯狂地点击"重新发送验证"链接.在这种情况下,90%的网站使用新令牌重新发送其链接,但也禁用所有以前的令牌.然后几个电子邮件以不可预测的顺序到达,而糟糕的用户必须猜测是徒劳的,哪一个(并且只有一个)仍然有效.现在为什么那些网站发现很难让几个令牌保持活跃,仅仅是为了这个案例,这是我无法理解的.

  • 最后,仍有一个难以忘怀的习惯让网站坚持使用所谓的"用户名".所以现在,除了我的电子邮件之外,我还要努力想出这个独特的用户名,与以前的用户不同!非常感谢你让它变得甜美而简单!我自己处理它的方法是使用我的电子邮件作为用户名.可悲的是,仍然有网站不接受它!然后,如果一些有趣的类型使用我的电子邮件作为他 如果您的电子邮件是bill@gates.com,那就不那么不现实了.但为什么不使用电子邮件和密码来避免所有这些混乱?


这里有一些可能的指导方针来减轻用户的痛苦:

  • 如果你绝对需要,只强迫我登录/给我,让我有机会选择不参加!

  • 使它成为一个页面形式,所以我知道我在做什么,不用说,尽可能少使用输入字段.理想情况下只有电子邮件和密码(可能两次),没有用户名!

  • 将您的登录表单显示为页面顶部的小窗口而不重新加载,并允许我从该窗口单击一下即可将其删除.不要强迫我寻找"关闭"按钮,或者更糟糕的是,我可能会对其他东西感到困惑!

  • 帐户让用户点击来回和重新加载按钮.重新加载时不要清除表单!根本不要放清楚按钮!偶然点击太容易了.您要求我填写的数据首先不应该太久,我无法在不需要"帮助"清除的情况下重新输入.


现在来质疑Q2.在这里,我们有众所周知的冲突解决问题,只要两个数据需要合并就会发生.例如,匿名数据和注册的用户数据,以及每当两个用户修改相同数据,或者同一用户在不同时间从不同设备修改它,或者本地存储的数据与服务器数据冲突时,等等.

但无论来源是什么,问题总是一样的.我们有两个数据,比如两个对象$ obj1和$ obj2,你需要生成你的单个合并对象$ obj3.逻辑可以像服务器对象总是获胜的规则一样简单,或者最后修改的对象总是获胜,或者最后修改的对象键总是获胜或者更复杂的逻辑.这实际上取决于您的应用程序的性质.但在每种情况下,您需要做的就是使用参数$ obj1,$ obj2编写逻辑函数,返回$ obj3.

在许多情况下可能起作用的解决方案是在每个对象属性(键)上存储时间戳,并在同步时让最新更改的键获胜.这例如考虑了当同一用户从不同设备匿名时修改不同属性的情况.

想象一下,我昨天在设备AA上修改了密钥A和B,然后今天从设备BB登录进入另一个B并将其保存到服务器,然后切换回我的设备AA,在那里我是匿名的,进入另一个A而不改变从昨天起老B,然后意识到我要登录并同步.然后我的本地B显然是老了,显然不应该覆盖我最近在设备BB上更改的B的值.在这个看似复杂的情况下,上述解决方案可以无缝有效地工作.相反,仅将时间戳放在整个对象上是错误的.

现在在某些情况下,保留两个对象是有意义的,例如通过添加额外的属性来区分它们,就像在Radek的问题中建议的情况1那样.例如,Dropbox将"用户X的冲突副本"添加到文件末尾.就像在Dropbox案例中一样,这对于协作应用程序来说是明智的,用户喜欢使用某些版本控制.但是,在这些情况下,您作为开发人员只需保存两份副本并让用户处理该问题.

另一方面,如果你必须根据用户的数据编写一个复杂的逻辑,那么两个不同的副本可能会成为一场噩梦.在这种情况下,我会将数据分成两组(例如,创建两个对象).第一组具有表示整个应用程序状态的数据,这是唯一的重要.对于该数据,我将使用上述或类似的冲突解决方案.然后第二组是用户特定的,我将两个数据存储在数据库中的两个单独的条目,正确标记它们(如Dropbox一样),然后让用户处理他们项目的两个(或更多)条目的列表.

最后,如果数据库管理的额外复杂性使得开发人员感到不安,并且由于Radek要求提供资源参考,我想通过提及博客条目StackMob offline Sync "一次性杀死两只苍蝇" ,其解决方案同时提供数据库和用户管理功能,从而减轻开发人员的痛苦.当然,在搜索数据并发,冲突解决等方面时,可以找到更多信息.

总而言之,我必须添加强制性免责声明,这里所写的所有内容仅仅是我自己的想法和建议,每个人都应该自担风险,如果你突然得到太多满意的用户使你的系统崩溃,不要让我负责: )

由于我自己正在开发一个应用程序,我正在实现所有这些方面,我当然非常有兴趣听取其他意见以及其他人对该主题的评论.


rya*_*234 7

根据我的经验 - 无论是作为需要登录的网站的用户,还是作为使用登录用户的开发人员 - 我都认为我从未见过网站的行为方式.

常见的模式是让用户匿名,并且当他们第一次做一些需要保存状态的事情时,会提示他们登录.然后记住上一个操作,用户可以继续.例如,如果他们尝试向购物车添加内容,则会提示他们登录,然后在登录后,该商品就会出现在他们的购物车中.

我想有些地方会允许你填充购物车,然后登录购物车与具体用户相关联的地方.

我将创建一个具有站点交互状态的SessionUser对象和一个名为UserId的字段,用于检索名称,地址等其他内容.

对于匿名用户,我将使用UserId的空引用创建SessionUser对象.这意味着我们无法解析名称或地址,但我们仍然可以保存状态.他们正在执行的操作,他们正在查看的页面等.

一旦他们登录我们就不必合并两个对象,我们只填充SessionUser中的UserId字段,现在我们可以遍历一个对象图来获取名称,电子邮件,地址或其他任何内容.

  • 去亚马逊,登录,把东西放在篮子里,打开另一个浏览器并放入其他东西.现在去结帐. (3认同)