Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

ะ’ ์ด์ „ ๊ธฐ์‚ฌ ๋ชจ๋ธ๊ณผ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ฅผ ํ†ตํ•ด ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ œํ’ˆ์„ Magento 2๋กœ ๊ฐ€์ ธ์˜ค๋Š” ํ”„๋กœ์„ธ์Šค๋ฅผ ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ ๋ฐฉ๋ฒ•์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ์†๋„๊ฐ€ ๋งค์šฐ ๋Š๋ฆฝ๋‹ˆ๋‹ค. ๋‚ด ๋…ธํŠธ๋ถ์€ ์ดˆ๋‹น ์•ฝ ํ•˜๋‚˜์˜ ์ œํ’ˆ์„ ์ƒ์‚ฐํ•˜๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ์—ฐ์†์—์„œ๋Š” ํ‘œ์ค€ Magento 2 ๋ฉ”์ปค๋‹ˆ์ฆ˜(๋ชจ๋ธ, ํŒฉํ† ๋ฆฌ, ์ €์žฅ์†Œ)์„ ์šฐํšŒํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ง์ ‘ ์ž…๋ ฅํ•˜์—ฌ ์ œํ’ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋Œ€์ฒด ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•ฉ๋‹ˆ๋‹ค. ์ œํ’ˆ์„ ๊ฐ€์ ธ์˜ค๋Š” ๋‹จ๊ณ„์˜ ์ˆœ์„œ๋Š” MySQL์—์„œ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋งž๊ฒŒ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฑ…์ž„ ๋ถ€์ธ: Magento์—๋Š” ๋‹ค์Œ์„ ์œ„ํ•œ ๊ธฐ์„ฑ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ ์•„๋งˆ๋„ ๊ทธ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒƒ์— ๋Œ€ํ•œ CSV ํŒŒ์ผ ์ค€๋น„์—๋งŒ ๊ตญํ•œ๋˜์ง€ ์•Š๊ณ  ๊ฐ€์ ธ์˜ค๊ธฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ๋ณด๋‹ค ์™„๋ฒฝํ•˜๊ฒŒ ์ œ์–ดํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ cat์— ์˜ค์‹  ๊ฒƒ์„ ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค.

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

๋‘ ๊ธฐ์‚ฌ๋ฅผ ๋ชจ๋‘ ์ž‘์„ฑํ•˜์—ฌ ์ƒ์„ฑ๋œ ์ฝ”๋“œ๋Š” Magento ๋ชจ๋“ˆ์—์„œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.lancer32/mage2_ext_demo_import". ๋ฐ๋ชจ ๋ชจ๋“ˆ ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋”ฐ๋ผ์•ผ ํ•  ๋ช‡ ๊ฐ€์ง€ ์ œํ•œ ์‚ฌํ•ญ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ œํ’ˆ์€ ์ƒ์„ฑ๋˜๊ธฐ๋งŒ ํ•˜๊ณ  ์—…๋ฐ์ดํŠธ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.
  • ์ฐฝ๊ณ  XNUMX๊ฐœ
  • ๊ตฌ์กฐ ์—†์ด ์นดํ…Œ๊ณ ๋ฆฌ ์ด๋ฆ„๋งŒ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋Š” ๋ฒ„์ „ 2.3์„ ์ค€์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ผ ์ œํ’ˆ์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•œ JSON:

{
  "sku": "MVA20D-UBV-3",
  "name": "ะ—ะฐะณะปัƒัˆะบะฐ ะดะปั ะฟะปะพะผะฑะธั€ะพะฒะบะธ ะ’ะ47-29 IEK",
  "desc": "ะžะฑะตัะฟะตั‡ะตะฝะธะต ะดะพัั‚ัƒะฟะฐ ะบ ัƒัั‚ั€ะพะนัั‚ะฒะฐะผ ...",
  "desc_short": "ะ—ะฐะณะปัƒัˆะบะฐ ะดะปั ะฟะปะพะผะฑะธั€ะพะฒะบะธ ะ’ะ47-29 IEK ะฟั€ะตะดะฝะฐะทะฝะฐั‡ะตะฝะฐ ะดะปั ...",
  "price": 5.00,
  "qty": 25,
  "categories": ["ะšะฐั‚ะตะณะพั€ะธั 1", "ะšะฐั‚ะตะณะพั€ะธั 2"],
  "image_path": "mva20d_ubv_3.png"
}

์ฃผ์š” ๊ฐ€์ ธ์˜ค๊ธฐ ๋‹จ๊ณ„ ๊ฐœ์š”

  • ์ œํ’ˆ ์ž์ฒด ๋“ฑ๋ก
  • ์ œํ’ˆ๊ณผ ์›น์‚ฌ์ดํŠธ์˜ ์—ฐ๊ฒฐ
  • ๊ธฐ๋ณธ ์ œํ’ˆ ์†์„ฑ(EAV)
  • ์žฌ๊ณ  ๋ฐ์ดํ„ฐ(์ œํ’ˆ ์žฌ๊ณ  ์ˆ˜๋Ÿ‰)
  • ๋ฏธ๋””์–ด (์‚ฌ์ง„)
  • ์นดํƒˆ๋กœ๊ทธ ์นดํ…Œ๊ณ ๋ฆฌ์™€์˜ ์—ฐ๊ฒฐ

์ œํ’ˆ ๋“ฑ๋ก

๊ธฐ๋ณธ ์ œํ’ˆ ์ •๋ณด๋Š” ๋‹ค์Œ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. catalog_product_entity:

CREATE TABLE `catalog_product_entity` (
  `entity_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Entity Id',
  `attribute_set_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Attribute Set ID',
  `type_id` varchar(32) NOT NULL DEFAULT 'simple' COMMENT 'Type ID',
  `sku` varchar(64) DEFAULT NULL COMMENT 'SKU',
  `has_options` smallint(6) NOT NULL DEFAULT '0' COMMENT 'Has Options',
  `required_options` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Required Options',
  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation Time',
  `updated_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Update Time',
  PRIMARY KEY (`entity_id`),
  KEY `CATALOG_PRODUCT_ENTITY_ATTRIBUTE_SET_ID` (`attribute_set_id`),
  KEY `CATALOG_PRODUCT_ENTITY_SKU` (`sku`)
)

์ œํ’ˆ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ํ•ญ๋ชฉ์„ ์ƒ์„ฑํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์ตœ์†Œ ์ •๋ณด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • attribute_set_id
  • sku

์ถ”๊ฐ€์˜:

  • type_id โ€” ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด 'simple'์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ง์ ‘ ์“ฐ๋ ค๋ฉด Magento ์ž์ฒด์˜ DB ์–ด๋Œ‘ํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

function create($sku, $typeId, $attrSetId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity');
    $bind = [
        'sku' => $sku,
        'type_id' => $typeId,
        'attribute_set_id' => $attrSetId
    ];
    $conn->insert($table, $bind);
    $result = $conn->lastInsertId($table);
    return $result;
}

์ œํ’ˆ ๋“ฑ๋ก ํ›„ catalog_product_entity ๊ด€๋ฆฌ์ž ํŒจ๋„์˜ ์ œํ’ˆ ๊ทธ๋ฆฌ๋“œ(์นดํƒˆ๋กœ๊ทธ/์ œํ’ˆ).

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

์ œํ’ˆ๊ณผ ์›น์‚ฌ์ดํŠธ์˜ ๊ด€๊ณ„

์‚ฌ์ดํŠธ์™€ ์ œํ’ˆ์˜ ์—ฐ๊ฒฐ์— ๋”ฐ๋ผ ์ œํ’ˆ์„ ์ „๋ฉด์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋งค์žฅ๊ณผ ์ง„์—ด์žฅ์ด ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค.

function linkToWebsite($prodId, $websiteId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_website');
    $bind = [
        'product_id' => $prodId,
        'website_id' => $websiteId
    ];
    $conn->insert($table, $bind);
}

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

๊ธฐ๋ณธ ์ œํ’ˆ ์†์„ฑ

์ƒˆ๋กœ ๋“ฑ๋ก๋œ ์ œํ’ˆ์—๋Š” ์•„์ง ์ด๋ฆ„์ด๋‚˜ ์„ค๋ช…์ด ์—†์Šต๋‹ˆ๋‹ค. ์ด ๋ชจ๋“  ์ž‘์—…์€ ๋‹ค์Œ์„ ํ†ตํ•ด ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. EAV ์†์„ฑ. ๋‹ค์Œ์€ ์ œํ’ˆ์ด ์ „๋ฉด์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํ‘œ์‹œ๋˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ธฐ๋ณธ ์ œํ’ˆ ์†์„ฑ ๋ชฉ๋ก์ž…๋‹ˆ๋‹ค.

  • name
  • price
  • description
  • short_description
  • status
  • tax_class_id
  • url_key
  • visibility

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ œํ’ˆ์— ๋ณ„๋„์˜ ์†์„ฑ์ด ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค(ํ•ด๋‹น ์ฝ”๋“œ์—์„œ ์†์„ฑ์˜ ์‹๋ณ„์ž ๋ฐ ์œ ํ˜•์„ ๊ฐ€์ ธ์˜ค๋Š” ์„ธ๋ถ€ ์ •๋ณด๋Š” ์ƒ๋žต๋จ).

public function create($prodId, $attrCode, $attrValue)
{
    $attrId = /* get attribute ID by attribute code */
    $attrType = /* get attribute type [datetime|decimal|int|text|varchar]) by attribute code */
    if ($attrId) {
        /** @var MagentoFrameworkAppResourceConnection $this->resource */
        /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
        $conn = $this->resource->getConnection();
        $tblName = 'catalog_product_entity_' . $attrType;
        $table = $this->resource->getTableName($tblName);
        $bind = [
            'attribute_id' => $attrId,
            'entity_id' => $prodId,
            /* put all attributes to default store view with id=0 (admin) */
            'store_id' => 0,
            'value' => $attrValue
        ];
        $conn->insert($table, $bind);
    }
}

์†์„ฑ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ID์™€ ๋ฐ์ดํ„ฐ ์œ ํ˜•์„ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค(datetime, decimal, int, text, varchar), ๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ด€๋ฆฌ ์ฐฝ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ํ•ด๋‹น ํ…Œ์ด๋ธ”(store_id = 0).

์œ„ ์†์„ฑ์„ ์ œํ’ˆ์— ์ถ”๊ฐ€ํ•˜๋ฉด ๊ด€๋ฆฌ์ž ํŒจ๋„์— ๋‹ค์Œ ๊ทธ๋ฆผ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

์žฌ๊ณ  ๋ฐ์ดํ„ฐ

Magento ๋ฒ„์ „ 2.3๋ถ€ํ„ฐ ์žฌ๊ณ  ์ •๋ณด(์ œํ’ˆ ์ˆ˜๋Ÿ‰) ์ €์žฅ์„ ์ œ๊ณตํ•˜๋Š” ๋‘ ๊ฐœ์˜ ๋ณ‘๋ ฌ ํ…Œ์ด๋ธ” ์„ธํŠธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • cataloginventory_*: ์˜ค๋ž˜๋œ ๊ตฌ์กฐ;
  • inventory_*: ์ƒˆ๋กœ์šด ๊ตฌ์กฐ(MSI - ๋‹ค์ค‘ ์†Œ์Šค ์žฌ๊ณ );

๋‘ ๊ตฌ์กฐ ๋ชจ๋‘์— ์ธ๋ฒคํ† ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด ๊ตฌ์กฐ๋Š” ์•„์ง ์ด์ „ ๊ตฌ์กฐ๋กœ๋ถ€ํ„ฐ ์™„์ „ํžˆ ๋…๋ฆฝ๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. default ํ…Œ์ด๋ธ”์ด ํฌํ•จ๋œ ์ƒˆ๋กœ์šด ๊ตฌ์กฐ์˜ ์ฐฝ๊ณ  cataloginventory_stock_status ์œผ๋กœ inventory_stock_1).

์นดํƒˆ๋กœ๊ทธ์ธ๋ฒคํ† ๋ฆฌ_

Magneto 2.3์„ ๋ฐฐํฌํ•  ๋•Œ ์ฒ˜์Œ์—๋Š” 2๊ฐœ์˜ ํ•ญ๋ชฉ์ด ์žˆ์Šต๋‹ˆ๋‹ค. store_website, ์ด๋Š” ๊ด€๋ฆฌ ๋ฐ ๊ธฐ๋ณธ ํด๋ผ์ด์–ธํŠธ์˜ ๋‘ ์‚ฌ์ดํŠธ์— ํ•ด๋‹นํ•ฉ๋‹ˆ๋‹ค.

website_id|code |name        |sort_order|default_group_id|is_default|
----------|-----|------------|----------|----------------|----------|
         0|admin|Admin       |         0|               0|         0|
         1|base |Main Website|         0|               1|         1|

ํ…Œ์ด๋ธ” cataloginventory_stock ํ•ญ๋ชฉ์€ ํ•˜๋‚˜๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค:

stock_id|website_id|stock_name|
--------|----------|----------|
       1|         0|Default   |

์ฆ‰, ์šฐ๋ฆฌ์˜ ์˜ค๋ž˜๋œ ๊ตฌ์กฐ์—๋Š” ๋‹จ ํ•˜๋‚˜์˜ "์ฐฝ๊ณ "(stock) ํ–‰์ • ํ™ˆํŽ˜์ด์ง€๋กœ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๊ด€๋ฆฌ์ž ํŒจ๋„์„ ํ†ตํ•ด ์ƒˆ ํ•ญ๋ชฉ ์ถ”๊ฐ€ sources/stocks MSI(์ƒˆ ๊ตฌ์กฐ)์—์„œ๋Š” ์ƒˆ ํ•ญ๋ชฉ์ด ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. cataloginventory_stock.

์ด์ „ ๊ตฌ์กฐ์˜ ์ œํ’ˆ์— ๋Œ€ํ•œ ์žฌ๊ณ  ๋ฐ์ดํ„ฐ๋Š” ์ฒ˜์Œ์— ํ…Œ์ด๋ธ”์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.

  • cataloginventory_stock_item
  • cataloginventory_stock_status

์นดํƒˆ๋กœ๊ทธinventory_stock_item

function createOldItem($prodId, $qty)
{
    $isQtyDecimal = (((int)$qty) != $qty);
    $isInStock = ($qty > 0);
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('cataloginventory_stock_item');
    $bind = [
        'product_id' => $prodId,
        /* we use one only stock in 'cataloginventory' structure by default */
        'stock_id' => 1,
        'qty' => $qty,
        'is_qty_decimal' => $isQtyDecimal,
        'is_in_stock' => $isInStock,
        /* default stock is bound to admin website (see `cataloginventory_stock`) */
        'website_id' => 0
    ];
    $conn->insert($table, $bind);
}

์นดํƒˆ๋กœ๊ทธ์žฌ๊ณ _์žฌ๊ณ _์ƒํƒœ

function createOldStatus($prodId, $qty)
{
    $isInStock = ($qty > 0);
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('cataloginventory_stock_status');
    $bind = [
        'product_id' => $prodId,
        /* we use one only stock in 'cataloginventory' structure by default */
        'stock_id' => 1, 
        'qty' => $qty,
        'stock_status' => MagentoCatalogInventoryApiDataStockStatusInterface::STATUS_IN_STOCK,
        /* default stock is bound to admin website (see `cataloginventory_stock`) */
        'website_id' => 0 
    ];
    $conn->insert($table, $bind);
}

๋ชฉ๋ก_

์ฒ˜์Œ์— ์žฌ๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์ƒˆ๋กœ์šด ๊ตฌ์กฐ์—๋Š” 1"์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.์ถœ์ฒ˜"(inventory_source):

source_code|name          |enabled|description   |latitude|longitude|country_id|...|
-----------|--------------|-------|--------------|--------|---------|----------|...|
default    |Default Source|      1|Default Source|0.000000| 0.000000|US        |...|

๊ทธ๋ฆฌ๊ณ  ํ•˜๋‚˜ "์ฐฝ๊ณ "(inventory_stock):

stock_id|name         |
--------|-------------|
       1|Default Stock|

ยซ์ถœ์ฒ˜ยป๋Š” ์ œํ’ˆ์˜ ๋ฌผ๋ฆฌ์  ์ €์žฅ์†Œ๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค(๊ธฐ๋ก์—๋Š” ๋ฌผ๋ฆฌ์  ์ขŒํ‘œ์™€ ์šฐํŽธ ์ฃผ์†Œ๊ฐ€ ํฌํ•จ๋จ). "ะกะบะปะฐะด"๋Š” ์—ฌ๋Ÿฌ "์†Œ์Šค"์˜ ๋…ผ๋ฆฌ์  ๊ฒฐํ•ฉ์ž…๋‹ˆ๋‹ค(inventory_source_stock_link)

link_id|stock_id|source_code|priority|
-------|--------|-----------|--------|
      1|       1|default    |       1|

ํŒ๋งค์ฑ„๋„๊ณผ์˜ ์—ฐ๊ฒฐ์ด ์ผ์–ด๋‚˜๋Š” ์ˆ˜์ค€์—์„œ (inventory_stock_sales_channel)

type   |code|stock_id|
-------|----|--------|
website|base|       1|

๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ํŒ๋งค ์ฑ„๋„์ด ๊ฐ€์ •๋˜์–ด ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ ์—ฐ๊ฒฐ๋งŒ "์žฌ๊ณ "-"์›น ์‚ฌ์ดํŠธ"(์›น์‚ฌ์ดํŠธ ๋งํฌ๋Š” ์›น์‚ฌ์ดํŠธ ์ฝ”๋“œ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค - base).

ํ•˜๋‚˜ "์ฐฝ๊ณ "์—ฌ๋Ÿฌ ๊ฐœ์— ์—ฐ๊ฒฐ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค"์›์ฒœ"๊ทธ๋ฆฌ๊ณ  ํ•˜๋‚˜ "์ถœ์ฒ˜" - ์—ฌ๋Ÿฌ ๋ช…์—๊ฒŒ "์ฐฝ๊ณ "(๋‹ค๋Œ€๋‹ค ๊ด€๊ณ„). ์˜ˆ์™ธ๋Š” ๊ธฐ๋ณธ๊ฐ’ "์ถœ์ฒ˜"๊ทธ๋ฆฌ๊ณ "์ฐฝ๊ณ ". ๋‹ค๋ฅธ ์—”ํ„ฐํ‹ฐ์— ๋‹ค์‹œ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์ฝ”๋“œ ์ˆ˜์ค€์˜ ์ œํ•œ - ์˜ค๋ฅ˜ "๊ธฐ๋ณธ ์†Œ์Šค ๋˜๋Š” ๊ธฐ๋ณธ ์ฃผ์‹๊ณผ ๊ด€๋ จ๋œ ๋งํฌ๋ฅผ ์ €์žฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."). Magento 2์˜ MSI ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ "CQRS์™€ Event Sourcing์„ ์ด์šฉํ•œ ์ฐฝ๊ณ  ๊ด€๋ฆฌ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค. ์„ค๊ณ„".

๊ธฐ๋ณธ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•˜๊ณ  ๋ชจ๋“  ์ธ๋ฒคํ† ๋ฆฌ ์ •๋ณด๋ฅผ ์†Œ์Šค์— ์ถ”๊ฐ€ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. default, ์ฝ”๋“œ๊ฐ€ ์žˆ๋Š” ์›น์‚ฌ์ดํŠธ์™€ ์—ฐ๊ฒฐ๋œ ํŒ๋งค ์ฑ„๋„์— ์ฐธ์—ฌํ•ฉ๋‹ˆ๋‹ค. base (์ƒ์ ์˜ ํ”„๋ŸฐํŠธ ์—”๋“œ์— ํ•ด๋‹น - ์ฐธ์กฐ store_website):

function createNewItem($sku, $qty)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('inventory_source_item');
    $bind = [
        'source_code' => 'default',
        'sku' => $sku,
        'quantity' => $qty,
        'status' => MagentoInventoryApiApiDataSourceItemInterface::STATUS_IN_STOCK
    ];
    $conn->insert($table, $bind);
}

๊ด€๋ฆฌ์ž ํŒจ๋„์—์„œ ์ œํ’ˆ์— ์žฌ๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋‹ค์Œ ๊ทธ๋ฆผ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

๋ฏธ๋””์–ด

๊ด€๋ฆฌ์ž ํŒจ๋„์„ ํ†ตํ•ด ์ œํ’ˆ์— ์ด๋ฏธ์ง€๋ฅผ "์ˆ˜๋™์œผ๋กœ" ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒฝ์šฐ ๊ด€๋ จ ์ •๋ณด๊ฐ€ ๋‹ค์Œ ํ‘œ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค.

  • catalog_product_entity_media_gallery: ๋ฏธ๋””์–ด ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ(์ด๋ฏธ์ง€ ๋ฐ ๋น„๋””์˜ค ํŒŒ์ผ)
  • catalog_product_entity_media_gallery_value: ๋ฏธ๋””์–ด๋ฅผ ์ œํ’ˆ ๋ฐ ์‡ผ์ผ€์ด์Šค์— ์—ฐ๊ฒฐ(ํ˜„์ง€ํ™”)
  • catalog_product_entity_media_gallery_value_to_entity: ๋ฏธ๋””์–ด๋ฅผ ์ œํ’ˆ์—๋งŒ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค(์•„๋งˆ๋„ ์ œํ’ˆ์˜ ๊ธฐ๋ณธ ๋ฏธ๋””์–ด ์ฝ˜ํ…์ธ ).
  • catalog_product_entity_varchar: ์ด๋ฏธ์ง€๊ฐ€ ์‚ฌ์šฉ๋˜๋Š” ์—ญํ• ์ด ์—ฌ๊ธฐ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.

์ด๋ฏธ์ง€ ์ž์ฒด๋Š” ๋””๋ ‰ํ† ๋ฆฌ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค ./pub/media/catalog/product/x/y/์–ด๋””์—์„œ x ะธ y โ€” ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ด๋ฆ„์˜ ์ฒซ ๋ฒˆ์งธ์™€ ๋‘ ๋ฒˆ์งธ ๋ฌธ์ž์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํŒŒ์ผ image.png ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ €์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ./pub/media/catalog/product/i/m/image.png, ํ”Œ๋žซํผ์ด ์นดํƒˆ๋กœ๊ทธ์˜ ์ œํ’ˆ์„ ์„ค๋ช…ํ•  ๋•Œ ์ด๋ฏธ์ง€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋“ฑ๋ก ๊ฒŒ์‹œ ์œ„์น˜ ./pub/media/catalog/product/ ๋ฏธ๋””์–ด ํŒŒ์ผ(ํŒŒ์ผ ์ž์ฒด๋ฅผ ๋ฐฐ์น˜ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค๋Š” ์ด ๋ฌธ์„œ์—์„œ ๋…ผ์˜๋˜์ง€ ์•Š์Œ):

function createMediaGallery($imgPathPrefixed)
{
    $attrId = /* get attribute ID by attribute code 'media_gallery' */
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity_media_gallery');
    $bind = [
        'attribute_id' => $attrId,
        'value' => $imgPathPrefixed,
        /* 'image' or 'video' */
        'media_type' => 'image',
        'disabled' => false
    ];
    $conn->insert($table, $bind);
    $result = $conn->lastInsertId($table);
    return $result;
}

๋“ฑ๋ก๋˜๋ฉด ์ƒˆ ๋ฏธ๋””์–ด ํŒŒ์ผ์— ์‹๋ณ„์ž๊ฐ€ ํ• ๋‹น๋ฉ๋‹ˆ๋‹ค.

๋“ฑ๋ก๋œ ๋ฏธ๋””์–ด ํŒŒ์ผ์„ ๊ธฐ๋ณธ ์ƒ์ ์˜ ํ•ด๋‹น ์ œํ’ˆ๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

function createGalleryValue($mediaId, $prodId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity_media_gallery_value');
    $bind = [
        'value_id' => $mediaId,
        /* use admin store view by default */
        'store_id' => 0,
        'entity_id' => $prodId,
        'label' => null,
        /* we have one only image */
        'position' => 1,
        'disabled' => false
    ];
    $conn->insert($table, $bind);
}

์šฐ๋ฆฌ๋Š” ์–ด๋–ค ๋งค์žฅ์—๋„ ๋ฌถ์ด์ง€ ์•Š๊ณ  ๋“ฑ๋ก๋œ ๋ฏธ๋””์–ด ํŒŒ์ผ์„ ํ•ด๋‹น ์ œํ’ˆ๊ณผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐ์ดํ„ฐ๊ฐ€ ์ •ํ™•ํžˆ ์–ด๋””์— ์‚ฌ์šฉ๋˜๋Š”์ง€, ์ด์ „ ํ…Œ์ด๋ธ”์˜ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผ์ด ๋ถˆ๊ฐ€๋Šฅํ•œ ์ด์œ ๋Š” ๋ช…ํ™•ํ•˜์ง€ ์•Š์ง€๋งŒ, ์ด ํ…Œ์ด๋ธ”์ด ์กด์žฌํ•˜๊ณ  ์ œํ’ˆ์— ์‚ฌ์ง„์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ์—ฌ๊ธฐ์— ๊ธฐ๋ก๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ทธ๊ฒŒ ๋‹ค์ž…๋‹ˆ๋‹ค.

function createGalleryValueToEntity($mediaId, $prodId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_product_entity_media_gallery_value_to_entity');
    $bind = [
        'value_id' => $mediaId,
        'entity_id' => $prodId
    ];
    $conn->insert($table, $bind);
}

Catalog_product_entity_varchar

๋ฏธ๋””์–ด ํŒŒ์ผ์€ ๋‹ค์–‘ํ•œ ์—ญํ• ๋กœ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(ํ•ด๋‹น ์†์„ฑ ์ฝ”๋“œ๋Š” ๊ด„ํ˜ธ ์•ˆ์— ํ‘œ์‹œ๋จ).

  • ๋ฒ ์ด์Šค(image)
  • ์ž‘์€ ์ด๋ฏธ์ง€(small_image)
  • ์ธ๋„ค์ผ(thumbnail)
  • ๊ฒฌ๋ณธ ์ด๋ฏธ์ง€(swatch_image)

์—ญํ• ์„ ๋ฏธ๋””์–ด ํŒŒ์ผ์— ์—ฐ๊ฒฐํ•˜๋Š” ๊ฒƒ์€ ์ •ํ™•ํžˆ ๋‹ค์Œ์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. catalog_product_entity_varchar. ๋ฐ”์ธ๋”ฉ ์ฝ”๋“œ๋Š” "๊ธฐ๋ณธ ์ œํ’ˆ ์†์„ฑ".

๊ด€๋ฆฌ์ž ํŒจ๋„์—์„œ ์ œํ’ˆ์— ์ด๋ฏธ์ง€๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

๋ฒ”์ฃผ

์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋ฐ์ดํ„ฐ๊ฐ€ ํฌํ•จ๋œ ๊ธฐ๋ณธ ํ…Œ์ด๋ธ”:

  • catalog_category_entity: ์นดํ…Œ๊ณ ๋ฆฌ ๋“ฑ๋ก;
  • catalog_category_product: ์ œํ’ˆ๊ณผ ์นดํ…Œ๊ณ ๋ฆฌ ๊ฐ„์˜ ์—ฐ๊ฒฐ;
  • catalog_category_entity_*: EAV ์†์„ฑ ๊ฐ’;

์ฒ˜์Œ์—๋Š” ๋นˆ Magento ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์นดํ…Œ๊ณ ๋ฆฌ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— 2๊ฐœ์˜ ์นดํ…Œ๊ณ ๋ฆฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค(์—ด ์ด๋ฆ„์„ ์ค„์˜€์Šต๋‹ˆ๋‹ค: crt - created_at, upd - updated_at):

entity_id|attribute_set_id|parent_id|crt|upd|path|position|level|children_count|
---------|----------------|---------|---|---|----|--------|-----|--------------|
        1|               3|        0|...|...|1   |       0|    0|             1|
        2|               3|        1|...|...|1/2 |       1|    1|             0|

id=1์ธ ์นดํ…Œ๊ณ ๋ฆฌ๋Š” ์ „์ฒด Magento ์นดํƒˆ๋กœ๊ทธ์˜ ๋ฃจํŠธ์ด๋ฉฐ ๊ด€๋ฆฌ์ž ํŒจ๋„์ด๋‚˜ ์ฒซ ํŽ˜์ด์ง€์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ID=2์ธ ์นดํ…Œ๊ณ ๋ฆฌ(๊ธฐ๋ณธ ์นดํ…Œ๊ณ ๋ฆฌ)๋Š” ๋ฉ”์ธ ์‚ฌ์ดํŠธ ๋ฉ”์ธ ์Šคํ† ์–ด์˜ ๋ฃจํŠธ ์นดํ…Œ๊ณ ๋ฆฌ(์ฃผ์š” ์›น์‚ฌ์ดํŠธ ์Šคํ† ์–ด)๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฐฐํฌ๋  ๋•Œ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค(์ฐธ์กฐ: ๊ด€๋ฆฌ์ž / ๋งค์žฅ / ๋ชจ๋“  ๋งค์žฅ). ๋˜ํ•œ ๋งค์žฅ ์ž์ฒด์˜ ๋ฃจํŠธ ์นดํ…Œ๊ณ ๋ฆฌ๋„ ์ „๋ฉด์— ํ‘œ์‹œ๋˜์ง€ ์•Š๊ณ  ํ•˜์œ„ ์นดํ…Œ๊ณ ๋ฆฌ๋งŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ด ๊ธ€์˜ ์ฃผ์ œ๋Š” ์—ฌ์ „ํžˆ ์ œํ’ˆ์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ์ด๋ฏ€๋กœ ์นดํ…Œ๊ณ ๋ฆฌ ์ƒ์„ฑ ์‹œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ง์ ‘ ์ž…๋ ฅํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  Magento ์ž์ฒด์—์„œ ์ œ๊ณตํ•˜๋Š” ํด๋ž˜์Šค(๋ชจ๋ธ ๋ฐ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ)๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ง์ ‘ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€์ ธ์˜จ ์ œํ’ˆ์„ ์นดํ…Œ๊ณ ๋ฆฌ์™€ ์—ฐ๊ด€์‹œํ‚ค๋Š” ๋ฐ์—๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค(์นดํ…Œ๊ณ ๋ฆฌ๋Š” ์ด๋ฆ„์œผ๋กœ ์ผ์น˜ํ•˜๋ฉฐ ์ผ์น˜ํ•˜๋Š” ๋™์•ˆ ์นดํ…Œ๊ณ ๋ฆฌ ID๊ฐ€ ๊ฒ€์ƒ‰๋ฉ๋‹ˆ๋‹ค).

function create($prodId, $catId)
{
    /** @var MagentoFrameworkAppResourceConnection $this->resource */
    /** @var MagentoFrameworkDBAdapterPdoMysql $conn */
    $conn = $this->resource->getConnection();
    $table = $this->resource->getTableName('catalog_category_product');
    $bind = [
        'category_id' => $catId,
        'product_id' => $prodId,
    ];
    $conn->insert($table, $bind);
}

"์นดํ…Œ๊ณ ๋ฆฌ 1" ๋ฐ "์นดํ…Œ๊ณ ๋ฆฌ 2" ์นดํ…Œ๊ณ ๋ฆฌ์— ์ œํ’ˆ ๋งํฌ๋ฅผ ์ถ”๊ฐ€ํ•œ ํ›„ ๊ด€๋ฆฌ ํŒจ๋„์˜ ์ œํ’ˆ ์„ธ๋ถ€ ์ •๋ณด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

์ถ”๊ฐ€ ์กฐ์น˜

๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์Œ ์ถ”๊ฐ€ ๋‹จ๊ณ„๋ฅผ ์™„๋ฃŒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ ์ธ๋ฑ์‹ฑ: ์ฝ˜์†”์—์„œ ํ˜ธ์ถœ ./bin/magento indexer:reindex;
  • ์ œํ’ˆ/์นดํ…Œ๊ณ ๋ฆฌ URL ์žฌ์ƒ์„ฑ: ' ํ™•์žฅ์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.elgentos/regenerate-์นดํƒˆ๋กœ๊ทธ-urlsยซ

์ถ”๊ฐ€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ ํ›„ ๊ด€๋ฆฌ์ž ํŒจ๋„์˜ ์ œํ’ˆ:

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

๊ทธ๋ฆฌ๊ณ  ์•ž์ชฝ์—:

Magento 2: ์ œํ’ˆ์„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๊ธฐ

๊ฐœ์š”

์ด์ „ ๊ธฐ์‚ฌ์™€ ๋™์ผํ•œ ์ œํ’ˆ ์„ธํŠธ(10๊ฐœ)๋ฅผ ์ตœ์†Œํ•œ 1๋ฐฐ ๋” ๋น ๋ฅด๊ฒŒ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค(10์ดˆ ๋Œ€ XNUMX). ์†๋„๋ฅผ ๋” ์ •ํ™•ํ•˜๊ฒŒ ์ถ”์ •ํ•˜๋ ค๋ฉด ๋” ๋งŽ์€ ์ˆ˜์˜ ์ œํ’ˆ(์ˆ˜๋ฐฑ ๊ฐœ ๋˜๋Š” ์ˆ˜์ฒœ ๊ฐœ ์ด์ƒ)์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ž…๋ ฅ ๋ฐ์ดํ„ฐ์˜ ํฌ๊ธฐ๊ฐ€ ์ด๋ ‡๊ฒŒ ์ž‘๋”๋ผ๋„ Magento์—์„œ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ(๋ชจ๋ธ ๋ฐ ๋ฆฌํฌ์ง€ํ† ๋ฆฌ)์˜ ์‚ฌ์šฉ์ด ์ค‘์š”ํ•˜๋‹ค๋Š” ๊ฒฐ๋ก ์„ ๋‚ด๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งŽ์€!) ํ•„์š”ํ•œ ๊ธฐ๋Šฅ์˜ ๊ฐœ๋ฐœ ์†๋„๋ฅผ ๋†’์ด๋ฉด์„œ ๋™์‹œ์— ์ƒ๋‹นํžˆ (๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค - ๋งŽ์€!) ๋ฐ์ดํ„ฐ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋“ค์–ด๊ฐ€๋Š” ์†๋„๋ฅผ ์ค„์ž…๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ์ ์œผ๋กœ ๋ฌผ์ด ์ –์€ ๊ฒƒ์œผ๋กœ ํŒ๋ช…๋˜์—ˆ์œผ๋ฉฐ ์ด๋Š” ๊ณ„์‹œ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด์ œ ๋‚˜๋Š” ๊ฐ€์ง€๊ณ  ๋†€ ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ๋ฅผ ๊ฐ–๊ฒŒ ๋˜์—ˆ๊ณ  ์•„๋งˆ๋„ ์ข€ ๋” ํฅ๋ฏธ๋กœ์šด ๊ฒฐ๋ก ์— ๋„๋‹ฌํ•˜๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ถœ์ฒ˜ : habr.com