엘로퀀트에 NoSQL 기능을? laravel-schemaless-attributes free

2019-07-23

MySQL JSON 컬럼


MySQL 5.7부터 JSON 컬럼을 지원한다. [ 메뉴얼] 물론 NoSQL 데이터베이스 만큼은 안되겠지만 RDB를 기반으로 하되 부분적으로 스키마가 없는 데이터도 다룰 이 있을 때 요긴하게 사용할 수 있을 것이다. 전자제품을 취급하는 쇼핑몰을 생각해보자. 품목마다 스펙이 다 달서 모든 상품에 같은 특성을 부여할 수 없다. 예를 들어 모니터는 화면 크기가 있지만, 하드 디스크는 화면 크기가 존재할 수 없다. 이런 경우에 특성만 자유롭게 스키마를 갖을 수 있도록 하면 유용할 것이다.


엘로퀀트에서 MySQL JSON 컬럼 사용하기


벨은 마이그레이션을 작성할 때 json() 메소드를 사용해서 JSON 컬럼을 추가할 수 있다.


Schema::create('products', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->json('properties');
$table->timestamps();
});

JSON 컬럼에 JSON 형이 아닌 데이터를 입력하면 저장할 때 에러가 난다.


// 문자열을 넣으면 안된다.
$product->properties = 'string';
$product->save(); // 에러!

// 배열을 넣으면 안된다.
$product->properties = ['array'];
$product->save(); // 에러!

$product->properties = json_encode('array');
$product->save(); // 성공!

$product->properties = json_encode(['array']);
$product->save(); // 성공!

데이터를 불러올 때도 JSON 형의 문자열을 가져오게 된다.


$product = Product::first();
echo $product->properties;
// 출력 { "size": "20", "color": "red" }

서 이를 사용하려면 JSON 디코딩을 해야한다.


$product = Product::first();
$properties = json_decode($product->properties);
echo $properties['size'];
// 출력 20

속성 캐스팅 함께 쓰기


입출력시 json 인코딩과 디코딩을 하는게 다소 귀찮다. 속성 캐스팅을 사용하면 자동으로 처리된다.


class Product extends Model
{
protected $casts = [
'properties' => 'array'
];

속성 캐스팅을 설정해두면 저장할 때도 배열을 바로 집어넣을 수 있다.


$product->properties = [
'size' => 20,
'color' => 'red'
];

물론 불러올 때도 자동으로 배열로 변환된다.


$product = Product::first();
$properties = $product->properties;
echo $properties['size'];
// 출력 20

laravel-schemaless-attributes 함께 쓰기


속성 캐스팅을 쓰는 것만으로도 꽤나 손쉬워졌지만 laravel-schemaless-attributes로 한 발 더 나아갈 수 있다. 설치 방법이나 사용법은 저장소의 설명을 참고하자. 여기서는 laravel-schemaless-attributes를 쓰면 어떤 점이 (조금 더) 편해지는지만 간단히 소개하겠다.


JSON 컬럼에 저장할 데이터의 부만 업데이트가 필요할 수 있다. 엘로퀀트만으로는 전체 JSON 데이터를 업데이트 하는 수 밖에 없다. 이를 위해 다음과 같이 임시 변수가 필요하다.


$properties = $product->properties;
$properties['size'] = 30;
$product->properties = $properties;
$product->save();

laravel-schemaless-attributes를 쓰면 아래와 같이 업데이트 하고자 하는 데이터만 바꿔서 바로 저장할 수 있다.


$product->properties->set('size', 30);
$product->save();

// 다차원 배열은 . 표기법으로 접근 가능하다.
$product->properties->set('appearance.size', 30);

이외에 쿼리 스코프 기능으로 검색을 할 수 있는 편의성이 있다.


// AND 조건으로 찾을 때
$product->withProperties(['size' => 10, 'color' => 'white'])->get();

// 찾는 조건이 하나
$product->withProperties('size', 10)->get();

이외에는 딱히 그냥 엘로퀀트를 쓰는 것에 비해 더 편한지 모르겠지만, 여러분은 이 패키지의 유용성을 더 느낄 수 있을지 모르니 공 저장소에 들러 나한테 필요한 기능이 있을지 살펴보고 쓸만하면 활용해보도록 하자.





이현석

메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.