【问题标题】:How can I make an array of [anyType] in laravel schema builder?如何在 laravel 模式构建器中创建 [anyType] 数组?
【发布时间】:2019-06-21 08:27:42
【问题描述】:

假设我有一个用户模式,其中将“爱好”链接到它,作为一个数组字符串。

我最近从 MongoDB 切换到 SQL,所以我的第一个想法是像 Mongo 一样接近它,并制作这样的东西;

var userSchema = new mongoose.Schema({
    username: String,
    password: String,
    hobbies: [String] });

所以,我尝试像这样对 laravel 模式构建器实现相同的逻辑;

Schema::create('users', function (Blueprint $table) {
      $table->string('username');
      $table->string('password');
      $table->array(string('hobbies'));  //array(string("test")) is just a mock syntax, I just researched how can I implement an array type here and learned that I can't

现在我想到了两种解决方案,一种是,找到一种方法以某种方式将其实现为数组, 或者,由于模式构建器不支持在此处放置数组类型,这不是我可以使用的最佳逻辑,我需要找到另一种将“用户”模式添加到“爱好”数组的方法。 (我唯一能想到的就是创建一个“爱好”模式并使用雄辩的关系将它们绑定在一起,但这似乎不太实用)

【问题讨论】:

    标签: php mysql sql laravel schema


    【解决方案1】:

    最好的方法是使用Eloquent Relationships。我不确定为什么在您的情况下它不实用。

    在您的特定情况下,User 可以有许多 HobbyHobby 也可以属于许多 User

    这就是你的人际关系的样子:

    // in App\User.
    public function hobbies()
    {
        return $this->hasMany(Hobby::class);
    }
    
    // in App\Hobby
    public function users()
    {
        return $this->belongsToMany(User::class);
    }
    

    您需要在您拥有的两个表中相应地定义您的外键。此外,many-to-many relationship 需要第三个表。在您的情况下,它将被称为:hobby_user

    要访问用户的爱好,您只需执行以下操作:

    App\User::find(1)->hobbies;
    

    虽然您也可以将爱好保存为字符串(.. 或 JSON),但如果您以后想做查询、报告等等,这可能会变得很麻烦。

    【讨论】:

      【解决方案2】:

      您可以使用 json 字段(MySql 支持开箱即用),

      https://dev.mysql.com/doc/refman/5.7/en/json.html

      在这里查看 laravel 文档:

      https://laravel.com/docs/5.7/migrations

      也许这对你也有帮助

      https://eloquentbyexample.com/course/lesson/lesson-9-json

      【讨论】:

        【解决方案3】:

        数组数据类型并非存在于所有数据库系统中。因此,您必须执行以下方法: 您可以使用 json->('') 方法,如下所示:

        Schema::create('users', function (Blueprint $table) {
              $table->string('username');
              $table->string('password');
              $table->json('hobbies');
        

        然后你的user 模型用户属性就像。

        class User extends Model
        {
            protected $xyz= [
            'hobbies' => 'array'
            ];
        }
        

        【讨论】:

        • 这行不通。 Laravel 模型中没有定义属性 $xyz
        【解决方案4】:

        您可以创建一个 JSON 列来存储一个数组。

        Schema::create('users', function (Blueprint $table) {
              $table->string('username');
              $table->string('password');
              $table->json('hobbies');
        

        然后在模型上,您可以在每次自动检索时将此列转换为数组。

        <?php
        
        namespace App;
        
        use Illuminate\Database\Eloquent\Model;
        
        class User extends Model
        {
            /**
             * The attributes that should be cast to native types.
             *
             * @var array
             */
            protected $casts = [
                'hobbies' => 'array',
            ];
        }
        

        正如另一个答案中提到的,关系数据库更常见的做法是创建一个额外的表来存储用户和爱好之间的关系。 如果您需要任何排序、搜索、级联删除/更新等。创建多对多关系而不是存储为数组更实用。

        【讨论】:

        • 首先感谢您的回答。我认为创建另一个模式/迁移“爱好”,然后将它们与 user > hasMany > hobbies 绑定,但是创建一个只有一列(字符串)的模式似乎有点奇怪,所以我告诉自己“即使这样,也可能有更好的方法将工作”。如果您说这是解决此问题的理想方法,我将使用雄辩的解决方案。干杯
        • 不客气。它可以防止许多问题,例如导致另一组问题的信息重复。例如。如果用户共享相同的爱好,然后您需要重命名此爱好,则必须更新所有这些用户。但是,当您有一个单独的爱好表时,您只需要更新一个会影响所有链接用户的行。如果您刚刚从 NoSQL 数据库切换到关系数据库,您可能想了解更多有关数据库设计模式的信息,尤其是数据库规范化实践en.wikipedia.org/wiki/Database_normalization
        猜你喜欢
        • 1970-01-01
        • 2011-02-09
        • 2013-02-17
        • 2015-11-18
        • 2018-06-11
        • 1970-01-01
        • 2018-10-15
        • 2019-07-08
        • 2021-08-11
        相关资源
        最近更新 更多