엘로퀀트에 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();

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




유료 구독자 전용 레터입니다.

한 달 1만원으로 매일 라라벨 관련 메일 받아보시고 과거 메일도 열람하세요. 일반 구독으로 공개글만 받아보실 수도 있습니다.

구독하기 버튼을 눌러주시면 구독과 동시에 xly에도 가입됩니다.

이현석

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