【问题标题】:To delete() or forceDelete(). A better way to determine删除()或强制删除()。更好的确定方法
【发布时间】:2019-06-05 02:04:51
【问题描述】:

我有一个包含 95 个表的数据库。系统用户存在users 表。许多其他表(95 个表中的 45 个)都有一个“created_by”,它指的是通过users.id 创建/添加行的用户。

现在。如果我想删除一个用户,我不能去做$user->delete(),我需要保留用户(软删除它),以防这个用户在其他表上创建了行。但是如果这个用户没有添加任何内容,那我应该继续$user->forceDelete()它。

我的问题是:有什么好的方法可以做到这一点吗?当我们有这么多表时,检查是否应该删除或强制删除用户。

我想我可以遍历表并检查用户的 id(要删除)是否存在,如果找到则它是 ->delete(),否则它是 ->forceDelete()。代码如下:

            // Get all tables
            $allTables = \DB::connection()->getDoctrineSchemaManager()->listTableNames();
            $tablesWithCreatedBy = [];
            foreach($allTables as $tableName){
                $tableColumns = \DB::getSchemaBuilder()->getColumnListing($tableName);

                if(in_array('created_by', $tableColumns)){
                    $tablesWithCreatedBy[] = $tableName;
                }
            }

            foreach($tablesWithCreatedBy as $tableName){
                $result = \DB::select(" SELECT created_by FROM `$tableName`
                    WHERE `created_by` = {$this->user->id} LIMIT 0, 1 ");

                if(isset($result[0])){
                    $this->user->delete();
                    break;
                }
            }

            // If wasn't trashed from the code above, then force delete the user!
            if(!$this->user->trashed()){
                $this->user->forceDelete();
            }

我觉得一定有更好的方法来做到这一点!有吗?

【问题讨论】:

  • 我不会强行删除其中任何一个。因为这种方式会让您在每次查询您的未来功能时都需要新的软删除用户时返回并更改此代码。将来,当您真正需要数据库中的这个小空间时;您可以为当天的状态编写代码并根据需要优化您的数据库。
  • @HilmiErdemKEREN 我不确定我理解你的意思。是的,我不能 forceDelete() 任何用户,但是当一个新用户被添加了一个被删除的用户使用的用户名时会发生什么?!您不能复制用户名,也不能更改删除用户的用户名,因为他/她可能会被恢复!
  • 看来我误解了你的问题,我的错。感觉你的问题是一个虚构的问题,这就是为什么我写我不会尝试在开发点的每个删除请求上以编程方式处理它。而是在需要时手动触发优化逻辑,或者在问题真正发生时使用event handlerGChistory tablecronjob 解决方案。

标签: php mysql database laravel eloquent


【解决方案1】:

您必须将records_count 添加到users 表中,每次用户将内容添加到其他表时都会递增,因此更改后的解决方案将很简单:

$result = ($this->user->records_count > 0) 
          ? $this->user->delete() 
          : $this->user->forceDelete(); 

或者编写 Laravel 控制台命令并在后台运行它,它将遍历数据库并进行清理操作。

【讨论】:

  • 当然,考虑过。但是我们说的是45张桌子!这是一个查询中的 where id IN ( SELECT created_by FROM X) OR ... 中的 45 个!我认为我的代码会更高效,因为它会在第一个找到的结果上停止,我知道这可能是第 45 个,但它也可能是第一个!
  • @Dewan159 想一想:应用程序和数据库之间的 45 个网络数据包(查询)或 2 个简单查询,让 db 完成工作。只需将索引添加到created_by - 你就会看到它的速度有多快。 p.s.索引为你做到了if checks
  • 也许你是对的,我不确定。但我试图找到一种优雅的方式来做到这一点,就桌子的数量而言。不过谢谢
  • @Dewan159 我认为您必须通过将records_count 添加到用户表中来简化体系结构,每次用户将内容添加到其他表时都会递增。因此,只需按该字段的状态进行操作
  • 好主意,使用 Laravel 的模型事件应该足够简单来实现它。但是我们已经有一个常设系统,这只会在尚未使用的系统上起作用,因为“records_count”将为零,但用户实际上仍然拥有数据!
猜你喜欢
  • 1970-01-01
  • 2010-12-20
  • 2020-07-28
  • 1970-01-01
  • 2020-07-26
  • 2019-02-20
  • 2016-07-22
  • 1970-01-01
  • 2012-07-19
相关资源
最近更新 更多