Php 这是一个好的会员支付数据库模式吗?

Php 这是一个好的会员支付数据库模式吗?,php,mysql,database,database-design,schema,Php,Mysql,Database,Database Design,Schema,我正在做一个项目来管理会员资格和其他类型的付款,但主要是会员资格,所以我创建了一个多态模式。任何想法,改进,出于某种原因,我不完全相信这个模式 正如您将看到的,让月份、年份为空的想法是允许保存任何其他付款的记录 CREATE TABLE IF NOT EXISTS `orders` ( `id` int(11) NOT NULL auto_increment, `partner_id` int(11) NOT NULL, `status` enum('pending','accept

我正在做一个项目来管理会员资格和其他类型的付款,但主要是会员资格,所以我创建了一个多态模式。任何想法,改进,出于某种原因,我不完全相信这个模式

正如您将看到的,让月份、年份为空的想法是允许保存任何其他付款的记录

CREATE TABLE IF NOT EXISTS `orders` (
  `id` int(11) NOT NULL auto_increment,
  `partner_id` int(11) NOT NULL,
  `status` enum('pending','accepted','cancelled','other') NOT NULL,
  `created_on` datetime NOT NULL,
  `concept` varchar(250) NOT NULL,
  `type` enum('membership','other') NOT NULL default 'membership',
  `source` enum('dineromail','casati','deposit','other') NOT NULL default 'dineromail',
  `notes` text NULL,
  `last_check_on` datetime default NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM  ;


CREATE TABLE IF NOT EXISTS `payments` (
  `id` int(11) NOT NULL auto_increment,
  `order_id` int(11) NOT NULL,
  `month` int(11) default NULL,
  `year` int(11) default NULL,
  `amount` float NOT NULL,
  PRIMARY KEY  (`id`),
  UNIQUE KEY `idx-order_id-month-year` (`order_id`,`month`,`year`)
) ENGINE=MyISAM ;


CREATE TABLE IF NOT EXISTS `partners` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `name` varchar(255) default NULL,
  `last_name` varchar(255) default NULL,

) ENGINE=MyISAM;

我还将包括收到付款的日期时间戳,并可能标记付款金额是否完整。

此外,我将在另一个表中提供来源,因为当应用程序增长时,您可能需要添加一些来源。

一些命令:

在这种情况下,我会考虑把月份变成一个枚举。它当然可以消除所有的歧义,除非你需要在这个领域做数学计算(这是之前的那个)

  • 货币应该存储为十进制,而不是浮点数。如果不是的话,奇怪的圆形东西会悄悄地进来

  • 没有订单价格的概念。如果他们少付工资,你怎么知道少付了多少

  • (有点与3相关)您通常会将其视为发票和付款类型表示(即使您不开具发票),因此这意味着一笔付款可以表示多个订单,反之亦然,因此这意味着多对多关系

  • 你在乎他们怎么付吗?(支票、信用卡、现金等)

  • 如果一个月只能收到一笔付款,为什么您要下多笔付款的订单?如果在同一个月内收到付款,您会怎么做?这里真的应该只有一对一的关系吗


  • 我同意jtyost2和Yishai先前的回答

    另一个注意事项是,我们的约定是以单数形式命名实体表,与类名匹配。也就是说,我们命名一行(命名类的一个实例),而不是命名集合。我们要问的问题是,这个表中的一行代表一个什么?我们在类和表中使用这个单数名称。(考虑到反对意见,是的,我确实认识到其他开发人员和其他框架遵循“表名多元化”的惯例。Rails在多元化方面甚至足够聪明,可以从Person类生成“people”表。)

    但是当表名开始变为复数时,我注意到通常只有一些表名变为复数,并且最终是单数名和复数名的混合

    `partner_id`
    `order_id`
    
    外键列的命名方式与我们命名它们的方式完全相同。对于外键列,我们遵循的约定是使用父表的名称,后跟_id。对于同一个表的多个关系,除了表名之外,我们还使用角色的名称,或者使用角色的名称代替表名

    我还建议在数据库中添加外键约束定义,即使MyISAM引擎没有强制执行它们

    在每个表的ID列上添加一个主键约束(在
    partner
    表中似乎缺少该约束)

    使用unqiue索引识别自然键

    在我看来,有两种支付模式:

    • 每次订单一次全额付款
    这就是亚马逊似乎使用的模式。订单上可能会有奖金优惠券和信用卡,但当涉及到付款时,我只为订单支付了一笔款项

    • 对账户余额的支付
    另一种模式是使用账户,并向账户应用费用、信用和付款。这是电话公司等公用事业公司常用的模式。这允许使用诸如当前余额和到期金额等概念

    在这方面,您的设计似乎与众不同。没有客户帐户的概念。但是,似乎一个订单会有多次付款。

    • 与十进制相同,而不是货币金额的浮动
    • 订单金额在哪里?你怎么知道他们是否欠钱
    • payment\u date
      添加到
      payments
      可以让您摆脱
      订单。最后检查
      以查看
    • 没有付款的识别信息吗?支票什么的?重复的条目似乎是个问题
    • payments.month
      payments.year
      的位置似乎很奇怪。如果这是一个会员制,我会假设你只需按部就班地付款。因此,从订单日期开始,6次付款可以同时获得6个月的会员资格。无需跟踪付款的月份(否则,当我支付第6个月和第7个月的费用,而不是1-5个月的费用时,这意味着什么?)
    …管理会员资格和其他付款的项目

    type
    enum('membership'、'other')

    允许月、年为空的想法是允许保存任何其他付款的记录

    CREATE TABLE IF NOT EXISTS `orders` (
      `id` int(11) NOT NULL auto_increment,
      `partner_id` int(11) NOT NULL,
      `status` enum('pending','accepted','cancelled','other') NOT NULL,
      `created_on` datetime NOT NULL,
      `concept` varchar(250) NOT NULL,
      `type` enum('membership','other') NOT NULL default 'membership',
      `source` enum('dineromail','casati','deposit','other') NOT NULL default 'dineromail',
      `notes` text NULL,
      `last_check_on` datetime default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=MyISAM  ;
    
    
    CREATE TABLE IF NOT EXISTS `payments` (
      `id` int(11) NOT NULL auto_increment,
      `order_id` int(11) NOT NULL,
      `month` int(11) default NULL,
      `year` int(11) default NULL,
      `amount` float NOT NULL,
      PRIMARY KEY  (`id`),
      UNIQUE KEY `idx-order_id-month-year` (`order_id`,`month`,`year`)
    ) ENGINE=MyISAM ;
    
    
    CREATE TABLE IF NOT EXISTS `partners` (
      `id` int(10) unsigned NOT NULL auto_increment,
      `name` varchar(255) default NULL,
      `last_name` varchar(255) default NULL,
    
    ) ENGINE=MyISAM;
    
    我在这里可能有点离谱,但听起来你好像在猜测未来的需求。如果是这样的话……不要这样做。没有一刀切的数据库模式——所以不要损害你正在为将来可能构建或可能不构建的应用程序构建的应用程序


    如果你有成员资格之外的具体用例,那么就分享它们。但是,我觉得最好使用两种不同的模型。
    类型
    和可空列通常会尖叫着说你试图将不同的东西塞进同一个表中。

    11位月是一个有趣的概念;11位年也是如此。它不是ar请您记录付款的实际日期,而不是付款申请的日期。如果某人发送了一个月的两张支票(通常是因为他们发送了一张支票,比如50美元,而忘记了正确的金额是60美元),会发生什么情况。您尚未指定任何外键。总体而言,您的架构尚未完成。如果需要添加其他检查,请仅
    CREATE TABLE [dbo].PaymentLog(  
        TransactionNumber int IDENTITY(1,1) NOT NULL,  
        ReferenceID int NOT NULL,  
        ReferenceType varchar(20) NULL,  
        TransactionID int NULL,  
        CustomerID int NULL,  
        PaymentMethod char(4) NULL,  
        LogType varchar(20) NULL,  
        UserHostAddress varchar(20) NULL,  
        Content nvarchar(4000) NULL,  
        ReasonCode varchar(20) NULL ,  
        Flag nvarchar(20) NULL ,  
        Note nvarchar(200) NULL,  
        [InDate] [datetime] NOT NULL CONSTRAINT DF_PaymentLog_InDate DEFAULT (GETDATE()),    
        [InUser] [nvarchar](100) NULL,  
        CONSTRAINT PK_PaymentLog PRIMARY KEY CLUSTERED (  
            TransactionNumber  
        )   
    )
    GO
    
    CREATE NONCLUSTERED INDEX [IX_PaymentLog_ReferenceID] ON [dbo].PaymentLog (  
        ReferenceID ASC  
    ) WITH FILLFACTOR = 90  
    GO