首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >拉勒维尔雄辩的3张桌子+1张枢轴表

拉勒维尔雄辩的3张桌子+1张枢轴表
EN

Stack Overflow用户
提问于 2020-11-27 16:12:49
回答 1查看 1.1K关注 0票数 0

我正在设计一个数据库来管理products。每个产品可能有多个color和多个size (例如,如果产品是T恤衫,相同的衬衫可以是小的、中等的或大的,并且是红色、绿色或蓝色的),所以我最终得到了3张桌子。

  • 颜色: id,name
  • Size: id,name
  • Product: id,name

我需要能够存储多少特定大小和特定颜色的产品在库存和价格以及每个。所以我用字段创建了第四个表:

  • color_id,size_id,product_id,quantity,价格

我为每个表建立了一个模型,并使用belongsToMany方法来定义它们之间的关系。“问题”在于它只允许指定两个表的外键(文档的示例是用户、角色和role_user)。

有没有办法用雄辩的口才来定义这些表之间的关系?

我需要能够查询数据库得到,例如,所有可用的绿色,大型产品。我知道如何使用纯SQL实现这一点,但我正在寻找一个更有说服力的版本。

EN

回答 1

Stack Overflow用户

发布于 2020-12-25 20:08:33

你所说的“产品”可能更好地命名为“样式”。产品表是具有数量和价格的枢轴表。是的,您有四个表:colorssizesstyles (示例见种子器),加上color_size_style透视表,我将称之为products

颜色、大小和样式表的迁移:

代码语言:javascript
复制
// create colors table
Schema::create('colors', function (Blueprint $table) {
    $table->id();
    $table->string('color', 100);
});

// create sizes table
Schema::create('sizes', function (Blueprint $table) {
    $table->id();
    $table->string('size', 100);
});

// create styles table
Schema::create('styles', function (Blueprint $table) {
    $table->id();
    $table->string('style', 100);
});

产品表的迁移,它是带有额外列数量和价格的color_size_style三向枢轴表:

代码语言:javascript
复制
// create products table
Schema::create('products', function (Blueprint $table) {
    $table->id();
    $table->foreignId('color_id')->constrained();
    $table->foreignId('size_id')->constrained();
    $table->foreignId('style_id')->constrained();
    $table->integer('quantity')->default(0);
    $table->decimal('price')->default(0.00);
});

颜色、大小和样式的模型

代码语言:javascript
复制
// define color model with size and style relationships
class Color extends Model
{
    public function sizes()
    {
        return $this->belongsToMany(Size::class, 'products');
    }
    public function styles()
    {
        return $this->belongsToMany(Style::class, 'products');
    }
}

// define size model with color and style relationships
class Size extends Model
{
    public function colors()
    {
        return $this->belongsToMany(Color::class, 'products');
    }
    public function styles()
    {
        return $this->belongsToMany(Style::class, 'products');
    }
}

// define style model with color and size relationships
class Style extends Model
{
    public function colors()
    {
        return $this->belongsToMany(Color::class, 'products');
    }
    public function sizes()
    {
        return $this->belongsToMany(Size::class, 'products');
    }
}

用于颜色、大小和样式的播种机:

代码语言:javascript
复制
// seed default colors
class ColorSeeder extends Seeder
{
    public function run()
    {
        $colors = [
            ['color' => 'black'],
            ['color' => 'white'],
            ['color' => 'gray'],
            ['color' => 'maroon'],
            ['color' => 'purple'],
            ['color' => 'navy'],
            ['color' => 'teal']
        ];

        DB::table('colors')->insert($colors);
    }
}

// seed default sizes
class SizeSeeder extends Seeder
{
    public function run()
    {
        $sizes = [
            ['size' => 'XS'],
            ['size' => 'S'],
            ['size' => 'M'],
            ['size' => 'L'],
            ['size' => 'XL'],
            ['size' => 'XXL']
        ];

        DB::table('sizes')->insert($sizes);
    }
}

// seed default styles
class StyleSeeder extends Seeder
{
    public function run()
    {
        $styles = [
            ['style' => 'Unisex Short Sleeve T-Shirt'],
            ['style' => 'Unisex Tank Top'],
            ['style' => 'Unisex Pullover Hoodie'],
            ['style' => 'Women\'s Short Sleeve T-Shirt'],
            ['style' => 'Women\'s Flowy Long Sleeve Shirt'],
            ['style' => 'Men\'s Polo Shirt']
        ];

        DB::table('styles')->insert($styles);
    }
}

现在,您可以在products表中添加一个条目:

代码语言:javascript
复制
$color = Color::inRandomOrder()->first();
$size = Size::inRandomOrder()->first();
$style = Style::inRandomOrder()->first();

$color->sizes()->attach($size, ['style_id' => $style->id]);

// or in any other combination:
// $color->styles()->attach($style, ['size_id' => $size->id]);
// $size->colors()->attach($color, ['style_id' => $style->id]);
// $size->styles()->attach($style, ['color_id' => $color->id]);
// $style->colors()->attach($color, ['size_id' => $size->id]);
// $style->sizes()->attach($size, ['color_id' => $color->id]);

要获得所有可能的组合(不是我们想要的):

代码语言:javascript
复制
select colors.color,sizes.size,styles.style from colors join sizes join styles;

为了得到我们标记为存在的产品:

代码语言:javascript
复制
select products.id,products.quantity,styles.style,sizes.size,colors.color,products.price
from products
join colors on colors.id=products.color_id
join sizes on sizes.id=products.size_id
join styles on styles.id=products.style_id
order by style,size,color;

虽然技术上没有必要,但您可能也想要一个产品模型。或者一个控制器就够了-我不确定。但这应该足以让你的头脑围绕三向支点的概念。;)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65040457

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档