【问题标题】:Patterns for building social network type applications?构建社交网络类型应用程序的模式?
【发布时间】:2009-12-28 08:53:40
【问题描述】:

我需要设计/架构/开发基于网络的社交网络类型应用程序。

基本功能:
- 用户在系统上创建帐户
- 用户同意互相“加为好友”
- 用户在系统内创建内容
- 用户指定哪些朋友可以查看/编辑他们创建的内容

这个核心功能肯定已经创建过很多次了吧?有没有关于如何实现这类事情的最佳实践模式?

我最感兴趣的是数据库的外观。

从 SQL 的角度来看(任何数据库)会是什么样子?
从 NOSQL 的角度来看(任何 NOSQL 数据库)会是什么样子?

我最感兴趣的是,数据库中的“内容可见性”问题是如何解决的?即数据库/应用程序如何确保只有经过批准的朋友才能看到用户创建的内容?

谢谢

【问题讨论】:

  • 看看您下面的评论“如何设计一个可能拥有数百万用户的系统”不仅限于社交网站,而是任何使用频繁的网站。亚马逊、谷歌、雅虎、微软等。通过搜索网络并阅读有关这些网站的案例研究,您将学到很多东西。

标签: sql design-patterns nosql social-networking architecture


【解决方案1】:

首先要解决的是数据库,SQL 看起来就像一个规范化的 sql 数据库。它还能是什么样子? nosql 数据库看起来像一堆名称值对文件。

建立社交网站的三种方法是在您对现有的流行和不受欢迎的网站进行大量研究以确定它们的架构和目标市场以及它们提供的特定服务之后这些市场。

  1. 从头开始构建您自己的(和/或使用框架)。像 Facebook、Beebo、Myspace 等。这显然是到达那里的最长路线,但这确实意味着当你这样做时你有东西要卖。平台、会员资格和 USP 都是您的,可以出售给鲁珀特默多克或任何人。
  2. 使用适合社交网站的 CMS 并使用基本功能、插件以及您自己的灵感来打入您的目标市场。在这个领域经常使用 Drupal(我也成功使用过),但 Joomla、Xaraya 和许多其他免费和付费的都可以使用。是的,更多的研究。当 Rupert 给你一个铃铛时,这里的卖点就更少了,因为基本工具可能是 GPL 的
  3. 使用您注册时提供的系统之一,然后使用工具构建您自己的系统,但提供了所有好东西,这些被称为白标网站。 Start looking here。如果有人想接管你,你就没有什么可卖的了。

如何处理“内容可见性”。当然,最初网站建设者会决定谁可以看到内容。仅限所有者、朋友、注册用户、普通大众?等等。但是这个决定必须符合网站的目标和政策。处理这个问题的最佳方法是通过基于角色的访问 RBAC see here for details

当您说您“需要设计/架构师/开发”时,这是因为内心的强烈冲动还是有人付钱给您?

无论哪种方式,请记住社交网络空间非常非常拥挤。如果您只是在构建另一个 YouTube 或 FaceBook,那么您不太可能产生使此类网站在商业上取得成功所需的临界数量。

如果是针对尚未满足的利基市场,例如“The Peckham and Brockley Exotic Bird Fanciers Club”然后您就知道您的市场是什么以及需要哪些功能,因此可以使用上述任何您认为最简单和最便宜的选项,但这取决于您分析和执行。

您当然可能有一个社交网站的想法,该网站是主流且未被其他网站覆盖,即您已经发现了神话中的“市场空白”。在这种情况下,去做吧,但要做好失望的准备。或者不。

【讨论】:

    【解决方案2】:

    您的设计应该是可维护的。这就是我的项目中的内容。

    1.) Application.Infrastructure

    • 所有业务对象的基类、业务对象集合、数据访问类以及我的自定义属性和实用程序作为扩展方法,通用验证框架。这决定了我最终的 .net 应用程序的整体行为组织。

    2.) Application.DataModel

    • 数据库的类型化数据集。
    • TableAdapters 已扩展以包含我可能需要的事务和其他功能。

    3.) Application.DataAccess

    • 数据访问类。
    • 使用底层类型化数据集查询数据库操作的实际位置。

    4.) Application.DomainObjects

    • 业务对象和业务对象集合。
    • 枚举。

    5.) Application.BusinessLayer

    • 提供可从表示层访问的管理器类。
    • HttpHandlers。
    • 我自己的 Page 基类。
    • 这里有更多内容..

    6.) Application.WebClientApplication.WindowsClient

    • 我的表示层
    • 从 Application.BusinessLayer 和 Application.BusinessObjects 获取引用。

    Application.BusinessObjects 在整个应用程序中使用,并在需要时跨越所有层 [Application.DataModel 和 Application.Infrastructure 除外]

    我所有的查询都只定义了 Application.DataModel。

    Application.DataAccess 作为任何数据访问操作的一部分返回或获取业务对象。业务对象是在反射属性的帮助下创建的。每个业务对象都标有到数据库中目标表的属性映射,业务对象中的属性标有与相应数据库表中目标列的属性映射。

    我的验证框架允许我在指定的 ValidationAttribute 的帮助下验证每个字段。

    我的框架大量使用属性来自动化大多数繁琐的任务,例如映射和验证。我还可以将新功能作为框架中的新方面。

    示例业务对象在我的应用程序中如下所示。

    User.cs

    [TableMapping("Users")]
    public class User : EntityBase
    {
        #region Constructor(s)
        public AppUser()
        {
            BookCollection = new BookCollection();
        }
        #endregion
    
        #region Properties
    
        #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute
    
        private System.Int32 _UserId;
    
        private System.String _FirstName;
        private System.String _LastName;
        private System.String _UserName;
        private System.Boolean _IsActive;
    
        [DataFieldMapping("UserID")]
        [DataObjectFieldAttribute(true, true, false)]
        [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")]
        public override int Id
        {
            get
            {
                return _UserId;
            }
            set
            {
                _UserId = value;
            }
        }
    
        [DataFieldMapping("UserName")]
        [Searchable]
        [NotNullOrEmpty(Message = "Username Is Required.")]
        public string UserName
        {
            get
            {
                return _UserName;
            }
            set
            {
                _UserName = value;
            }
        }
    
        [DataFieldMapping("FirstName")]
        [Searchable]
        public string FirstName
        {
            get
            {
                return _FirstName;
            }
            set
            {
                _FirstName = value;
            }
        }
    
        [DataFieldMapping("LastName")]
        [Searchable]
        public string LastName
        {
            get
            {
                return _LastName;
            }
            set
            {
                _LastName = value;
            }
        }
    
        [DataFieldMapping("IsActive")]
        public bool IsActive
        {
            get
            {
                return _IsActive;
            }
            set
            {
                _IsActive = value;
            }
        }
    
        #region One-To-Many Mappings
        public BookCollection Books { get; set; }
    
        #endregion
    
        #region Derived Properties
        public string FullName { get { return this.FirstName + " " + this.LastName; } }
    
        #endregion
    
        #endregion
    
        public override bool Validate()
        {
            bool baseValid = base.Validate();
            bool localValid = Books.Validate();
            return baseValid && localValid;
        }
    }
    

    BookCollection.cs

    /// <summary>
    /// The BookCollection class is designed to work with lists of instances of Book.
    /// </summary>
    public class BookCollection : EntityCollectionBase<Book>
    {
        /// <summary>
        /// Initializes a new instance of the BookCollection class.
        /// </summary>
        public BookCollection()
        {
        }
    
        /// <summary>
        /// Initializes a new instance of the BookCollection class.
        /// </summary>
        public BookCollection (IList<Book> initialList)
            : base(initialList)
        {
        }
    }
    

    【讨论】:

      【解决方案3】:

      http://www.neo4j.org 这样的图形数据库是一个值得一看的选择。它非常适合社交网络(例如 http://blog.neo4j.org/2009/09/social-networks-in-database-using-graph.html)和基于 ACL 的安全性(例如 http://wiki.neo4j.org/content/ACL)。

      【讨论】:

        【解决方案4】:

        您应该首先研究现有的社交网络(Facebook、Myspace 等)。有大量关于如何实施的信息。

        【讨论】:

          【解决方案5】:

          社交网络成功的关键不是它所基于的技术,而是它们为用户解决的问题。如果用户喜欢它,即使你的技术很垃圾,你也注定会成功。

          [编辑] 它是如何实现的?检查任何基于 SQL 的用户角色系统。在这种情况下,每个用户也是一个角色,可以将其添加为“允许访问”任何对象。根据您拥有的对象数量以及控件的细粒度,这可能意味着您有一个包含三列的表:OBJECT, USER, ACCESS_TYPE 其中ACCESS_TYPE 可以是OWNERREAD(朋友)之一, WRITE(密友)。

          这个表会变得非常大,但几亿行对于今天的数据库来说并不少见。

          【讨论】:

          • 我对如何设计一个可能拥有数百万用户、内容可见性由朋友关系定义的系统感兴趣。那是怎么做的?该网站是否在商业上取得成功在现阶段无关紧要。
          【解决方案6】:

          正如 Aaroon 所指出的,您应该首先问自己要解决什么问题。

          您希望人们分享哪些内容?它真的应该只对朋友可见吗?如果您让内容公开可见,它会更容易和可扩展,因为显示的内容不取决于谁在观看页面,您可以轻松地缓存它。公开可用的用户生成内容吸引了新用户。

          如果您想限制访问并让用户有机会将朋友组附加到资源,我会使用简单的基于组的访问控制。让每个资源都有一组可以编辑资源的用户和一组可以看到它的用户。

          这样每个资源都有两个单值属性,每个用户都属于有限数量的组。您可以将 view-group 和 edit-group 属性附加到存储在 NOSQL 数据库、搜索引擎(如 Lucene/Sphinx)或 SQL 数据库中的行中的文档。查询用户可用的内容时,传递用户所属的所有组(在 SQL 中,您将使用 IN 子句,在 Sphinx 中使用 setFilter('view-group', array(2,3,4))。数据库将仅返回用户可用的内容。因为您只附加 2整数值(视图组和编辑组)到文档,您可以将它们存储在内存中,从而使搜索快速且可扩展。

          【讨论】:

            【解决方案7】:

            最终看起来 Elgg 或 Dolphin 可能会满足我们的要求。这些似乎是用于滚动您自己的社交网络的 PHP 框架。我查看了 Facebook 平台,但没有任何地方清楚地解释它是什么 - 它似乎是 facebook 代码,但也许它只是插件 API 或其他东西的代码。

            【讨论】:

            • 感谢 Elgg 的链接。我以前没听说过。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2015-10-24
            • 1970-01-01
            • 2014-01-21
            • 1970-01-01
            • 1970-01-01
            • 2010-11-29
            • 2011-05-09
            相关资源
            最近更新 更多