首页 > 解决方案 > 在 MySql 中创建具有许多外键的大表

问题描述

我正在创建一个应用程序,我必须在其中保存有关用户教育的信息,然后我将向他们展示。每个用户可能有 1、2 或更多教育。我正在使用 laravel Schema builder 创建此表。这是代码

    Schema::create('educations', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('user_id')->unsigned();
        $table->date('from')->nullable();
        $table->date('to')->nullable();
        $table->integer('country_id')->unsigned();
        $table->integer('city_id')->unsigned();
        $table->integer('university_id')->unsigned();
        $table->integer('faculty_id')->unsigned()->nullable();
        $table->integer('speciality_id')->unsigned()->nullable();
        $table->integer('degree_id')->unsigned()->nullable();
        $table->string('image', 100)->nullable();
        $table->text('additional')->nullable();


        $table->index('university_id');
        $table->index('faculty_id');
        $table->index('country_id');
        $table->index('city_id');
        $table->index('degree_id');
        $table->index('speciality_id');


        $table->foreign('user_id')
            ->references('id')->on('users')
            ->onDelete('cascade');

        $table->foreign('faculty_id')
            ->references('id')->on('faculties')
            ->onDelete('cascade');

        $table->foreign('degree_id')
            ->references('id')->on('degrees')
            ->onDelete('cascade');

        $table->foreign('speciality_id')
            ->references('id')->on('specialities')
            ->onDelete('cascade');

        $table->foreign('university_id')
            ->references('id')->on('universities')
            ->onDelete('cascade');

        $table->foreign('country_id')
            ->references('id')->on('countries')
            ->onDelete('cascade');

        $table->foreign('city_id')
            ->references('id')->on('cities')
            ->onDelete('cascade');
    });

MySql 代码:

CREATE TABLE `educations` 
( 
    `id`            INT UNSIGNED NOT NULL auto_increment PRIMARY KEY, 
    `user_id`       INT UNSIGNED NOT NULL, 
    `from`          DATE NULL, 
    `to`            DATE NULL, 
    `country_id`    INT UNSIGNED NOT NULL, 
    `city_id`       INT UNSIGNED NOT NULL, 
    `university_id` INT UNSIGNED NOT NULL, 
    `faculty_id`    INT UNSIGNED NULL, 
    `speciality_id` INT UNSIGNED NULL, 
    `degree_id`     INT UNSIGNED NULL, 
    `image`         VARCHAR(100) NULL, 
    `additional`    TEXT NULL 
) 

DEFAULT CHARACTER SET utf8mb4 COLLATE 'utf8mb4_unicode_ci') 

所以我有一个问题:当我想获得一个用户的所有教育时,我必须在几乎 7 个表上运行 join 或使用 laravel 查询生成器并在页面加载时运行许多查询。我的数据库设计正确吗?

我在每列上使用外键的原因是用户必须从我在数据库中的可变列表中选择他们的学院、大学、专业等。

任何答案都会有所帮助。谢谢..

标签: phpmysqlsqllaravellaravel-5

解决方案


我相信我可以在这些关系结构背后看到您的想法,但以我的拙见,它们并不完全正确,因为我觉得在某些情况下,列条目彼此之间没有直接关系。我会给你一些例子:

  1. 您的表名称是“教育”。1 位用户接受过多次教育,但 1 次教育不仅是为 1 位用户保留的。所以这是一个 n:m 关系,这就是为什么你需要 1 个表,称为 'educations',1 个表用于 'users' 和 1 个表,位于那些称为 'user_has_got_education' 的表之间。您的外键与 user_id 和 education_id 一起放在后一个表中。
  2. country_id、city_id、university_id、faculty_id 与教育没有直接关系。创建一个名为“国家”的表(国家 ID、国家名称、国家人口、国家代码、.....),然后以相同的方式创建一个名为“城市”的表。在这里它变得有点困难,因为一个city_id不一定是不同的,因为可能有两个city_name='London'的city_id,一个指伦敦(英国),一个指伦敦(美国,俄亥俄),一个指伦敦(美国) ,肯塔基州)。所以你至少在这里需要的是与“国家”和州/县/郡的表格关系 - 甚至可能还不够(例如,如果在俄亥俄州的美国有 2 个名为“伦敦”的城市)。我称之为“直接关系”。简而言之,您的列(外键)位于错误的位置,它们属于“直接连接的兄弟表”,而不是 > 进入“侄子表”。

尝试从一个逻辑直接关系到另一个并相应地“连接”您的表。我希望我能帮上忙,不过,这里不能真正给你一个完整的表结构。


推荐阅读