创建一个数据库来存储模块名称及其parent_module_id

时间:2019-01-08 00:13:14

标签: sql database database-design foreign-keys sequelize.js

好的,我有一个表,其中存储了所有模块或程序的名称,就像这样

+----+----------------+
|id  |module          |
+----+----------------+
|1   |node js         |
+----+----------------+
|2   |python          |
+----+----------------+
|3   |angular         |
+----+----------------+
|4   |ionic           |
+----+----------------+
|5   |tensorflow      |
+----+----------------+
|6   |jupyter notebook|
+----+----------------+

现在我想存储所有模块的父模块,例如我们需要安装nodejs才能开始使用ionic或对于tensorflow我们需要拥有python 。现在我有两个,我包括一个名为parent_id的列,该列是foreign_key引用同一表的id

+----+----------------+----------+
|id  |module          |parent_id |
+----+----------------+----------+
|1   |node js         |null      |
+----+----------------+----------+
|2   |python          |null      |
+----+----------------+----------+
|3   |angular         |1         |
+----+----------------+----------+
|4   |ionic           |1         |
+----+----------------+----------+
|5   |tensorflow      |2         |
+----+----------------+----------+
|6   |jupyter notebook|2         |
+----+----------------+----------+

这帮助我为父母提供了生育多个孩子的选择,例如nodejs有两个孩子,分别是角生和离子生。

我正在使用sequelize,并且已将关联设置为任何常规关联。

//--------- module.model.js------------//
'use strict';
module.exports = (sequelize, DataTypes) => {
  const Module = sequelize.define('Module', {
  }, {
    timestamps: false
  });
  module.associate = function(models) {
    Module.hasMany(Module, {
      foreignKey: 'parent_id',
    });
    Module.belongsTo(Module, {
      foreignKey: 'parent_id',
    });
  };
  return Module;
};

//--------------- index.js-------------//
const models = require('./models');  //module.models.js

async function start() {
  let modules = await models.Module.findAll({
    include: [{
      model: models.Module
    }]
  });
  console.log(modules);
}
start();

输出有点像这样:

[{id: 1, module: 'node js', Module: [
    {id: 3, module: 'angular'},
    {id: 4, module: 'ionic'}
  ]},
 {id: 2, module: 'python', Module: [
    {id: 5, module: 'tensorflow'},
    {id: 6, module: 'jupyter notebook'}
  ]},
 {id: 3, module: 'angular', Module: []},
 {id: 4, module: 'ionic', Module: []},
 {id: 5, module: 'tensorflow', Module: []},
 {id: 6, module: 'jupyter notebook', Module: []}]

这是很期望的,但是我想在子项内部获取父模块数组,就像这样:

[{id: 1, module: 'node js', Module: []},
 {id: 2, module: 'python', Module: []},
 {id: 3, module: 'angular', Module: [
    {id: 1, module: 'node js'}
  ]},
 {id: 4, module: 'ionic', Module: [
    {id: 1, module: 'node js'},
  ]},
 {id: 5, module: 'tensorflow', Module: [
    {id: 2, module: 'python'},
  ]},
 {id: 6, module: 'jupyter notebook', Module: [
    {id: 2, module: 'python'},
  ]}]

我知道我可以用相反的方式将parent_id列更改为child id映射模块,但这排除了父级有多个孩子的可能性,并且每个父级仅显示一个孩子。

+----+----------------+----------+
|id  |module          |child_id  |
+----+----------------+----------+
|1   |node js         |3         |
+----+----------------+----------+
|2   |python          |5         |
+----+----------------+----------+
|3   |angular         |null      |
+----+----------------+----------+
|4   |ionic           |null      |
+----+----------------+----------+
|5   |tensorflow      |null      |
+----+----------------+----------+
|6   |jupyter notebook|null      |
+----+----------------+----------+

因此如何通过包含第三个表来实现期望的输出,以及需要在关联或整个表结构中进行哪些修改,该表将具有两个指向同一表的前键,有点像这样,但这看起来并不这么传统,或者说老实话,我之前从未见过这样的东西,所以我不确定这是否正确。

  +-------------------------------------------------
  |                                     |          |
+----+----------------+        +----+---------+----------+
|id  |module          |        |id  |child_id |parent_id |
+----+----------------+        +----+---------+----------+
|1   |node js         |        |1   | 3       | 1        |
+----+----------------+        +----+---------+----------+
|2   |python          |        |2   | 4       | 1        |
+----+----------------+        +----+---------+----------+
|3   |angular         |        |3   | 5       | 2        |
+----+----------------+        +----+---------+----------+
|4   |ionic           |        |4   | 6       | 2        |
+----+----------------+        +----+---------+----------+
|5   |tensorflow      |
+----+----------------+
|6   |jupyter notebook|
+----+----------------+

因此,我很困惑如何解决此问题,我也刚好是新手和初学者。提前致谢。

3 个答案:

答案 0 :(得分:2)

您可以创建一个相关的多对多表,如下所示:-

创建表语言(    lng_id INT NOT NULL,    lng_name VARCHAR(40)NOT NULL,    说明VARCHAR(100)非空,    图片BLOB NOT NULL,    主键(lng_id)

创建表dependency_lng(   lng_id1 INT NOT NULL,//与语言有关的FK   lng_id2 INT NOT NULL),//与语言有关的FK。    约束pk_dependency_lng主键(lng_id1,lng_id2)

如果需要,您可以在任何外键旁边添加任意数量的条目。

P.S:---如果需要,也不需要自动递增列。主键可以是(lng_id1,lng_id2)

答案 1 :(得分:0)

希望您需要一个自我推荐的协会。

module.associate = function(models) {
    Module.hasMany(Module, {
      foreignKey: 'parent_id',
      as:'sub_entry'
    })
  };

请注意,您不需要属于关联,并且需要为此关联添加关键字as

和您的查询

let modules = await models.Module.findAll({
    include: [{
      model: models.Module,
      as:'sub_entry'
    }]

希望这能满足您的期望。您不需要辅助表。

答案 2 :(得分:0)

自荐协会将起作用

module.associate = function(models) {
  Module.belongsTo(Module, {
    foreignKey: 'parent_id',
    as:'parent'
  })
};

请注意,我们需要具有belongsTo关联的as,而不是hasMany

因此具有常规查询

let modules = await models.Module.findAll({
  include: [{
    model: models.Module,
    as:'parent'
  }]
});

这将导致期望的结果

[{id: 1, module: 'node js', Module: []},
 {id: 2, module: 'python', Module: []},
 {id: 3, module: 'angular', Module: [
    {id: 1, module: 'node js'}
  ]},
 {id: 4, module: 'ionic', Module: [
    {id: 1, module: 'node js'},
  ]},
 {id: 5, module: 'tensorflow', Module: [
    {id: 2, module: 'python'},
  ]},
 {id: 6, module: 'jupyter notebook', Module: [
    {id: 2, module: 'python'},
  ]}]