Extra Form
PHP PHP 7.3
CMS Rhymix 2.0

안녕하세요.

mysql 조건문 질문 좀 드릴게요.

DB에 배열로 저장이 되는 필드가 있는데 이 배열중에서
하나의 조건이 있는것들만 SELECT 하고 싶은데 조건을 어떻게 해주어야 할까요?

 

    stutus
------------------
프리미엄||신규||종료
프리미엄|| ||종료
||신규||


이런식으로 배열로 저장이 되어 있습니다.

이중에 프리미엄이 들어 있는 행을 SELECT 해야한다면

WHERE status in ('프리미엄')  이런식으로 조건을 주면 될까요?

 

 

  • profile
    그렇게 하면 프리미엄 하나만 들어 있는 게 아니라 (다른 것들과 함께) 프리미엄이 포함된 데이터를 다 가져오게 되지 않나요?
    컬럼 속 배열에 들어가는 데이터가 정해진 것이라면, 신규나 종료 등에 대해 notin으로 조건을 거는 게 나을 것도 같은데요.
  • profile ?
    답변 감사드립니다^^

    컬럼 속 배열에 들어가는 데이터가 정해진 것이라면, 신규나 종료 등에 대해 notin으로 조건을 거는 게 나을 것도 같은데요.
    -> notion 에 대해 좀 더 설명해주실수 있을까요?
  • profile

    DB에는 배열이라는 것이 없습니다. 그냥 "||"라는 무의미한 문자열로 구분해서 "프리미엄||신규||종료"라는 문자열을 저장해 둔 것이겠죠.

     

    질문 전에 실제로 해보셨는지 모르겠지만, 이 경우 WHERE status IN ('프리미엄') 이라고 쿼리하면 문자열 전체가 정확하게 일치해야 하기 때문에 "프리미엄" 하나만 입력되어 있고 앞뒤에 "||" 같은 구분자도 붙어 있지 않아야 검색이 될 거예요.

     

    저런 상황에서 "프리미엄"이 포함된 것을 찾고 싶으시다면 WHERE status LIKE '%프리미엄%' 이렇게 사실상 풀 테이블 스캔의 형태를 띠어야 합니다. 검색 속도와 DB 부하는 당연히 안드로메다로 가겠죠. 만약 프리미엄이 항상 맨 앞에 나온다면 해당 컬럼에 인덱스를 걸고 WHERE status LIKE '프리미엄%' 이렇게 앞쪽 %를 떼는 방법으로 다소 최적화가 가능하겠지만, 중간이나 뒤에 있는 것은 이 방법으로 찾을 수 없으니 꼼짝없이 느려터진 LIKE %% 검색을 해야 합니다.

     

    아무 의미도 없는 문자열을 사용해서 배열을 억지로 저장해 놓고 다시 추출하려고 애쓰는 것보다는 아예 테이블을 분리해서 다대다 관계로 정규화하거나, JSON으로 저장한 후 MySQL 최신 버전에서 지원하는 JSON 쿼리 방식을 사용하는 것이 더 효율적입니다.

  • profile profile
    말씀해주셔서 찾아봤는데 MySQL 5.7부터 json 데이터 타입을 지원하는군요.
    그러면 모듈 만들 때 한번 시도해봐도 범용성이 있을까요? 제가 서버알못이라...
  • profile profile
    XML 스키마에서 json 타입으로 선언하고 insert/update시에는 json_encode 해서 문자열로 전달한다면 데이터를 넣는 것까지는 가능할 것 같습니다. 다만 select할 때 XML 쿼리에서는 json 검색 문법을 아직 지원하지 않으니 커스텀 쿼리를 쓰셔야겠네요.
  • profile profile
    json타입 저장은 이미 가능하군요. 여윽시!
    근데 여기서 한걸음 더 나아가서 documents나 members의 extra_vars 컬럼을 json 타입으로 바꾼다든가 하는 것은 기존 자료의 호환 문제 때문에 안 되겠죠?
  • profile profile
    네, 코어에서만 쓴다면 상관없겠지만 임의로 가져와서 unserialize한 후 조작하려고 하는 서드파티 자료가 많기 때문에 json을 넣으면 기존 데이터가 유실될 우려가 있습니다. json을 한 번 거치고 나면 오브젝트와 연관배열을 구분할 수 없게 된다는 단점도 꽤 심각해요.
  • profile profile

    마지막으로 궁금한 게 하나 더 있는데요.
    데이터를 xml이나 json 파일 형태로 캐시파일처럼 저장해서 불러오는 것과, 지금 경우처럼 db에 문자열로 저장해서 불러오는 것 중에서 어느 것이 좀 더 효율적인가요?
    언뜻 생각으로는 검색 기능까지 생각하면 db저장이 나을 것도 같은데요. 서버 부하를 생각하면 파일 저장이 나을 것 같기도 하구요.

    자꾸 질문드려서 죄송합니다;;;
    이럴거면 따로 질문글을 파거나 오픈채팅방을 이용하는 게 나을 뻔했어요ㅜ

  • profile profile

    이미지나 동영상 등 바이너리 데이터 외에는 모두 DB에 저장하는 것이 원칙입니다. PK로 검색한다면 서버 부하도 거의 눈에 띄지 않을뿐더러, 문제가 된다면 오브젝트 캐시를 활용하면 그만이지요. 자잘한 파일을 만들지 마세요. 지레짐작으로 섣불리 마이크로-최적화를 시도하면 항상 뒤탈이 납니다.

    코어에서도 포인트, 서명, 썸네일 등 작은 파일을 쓸데없이 너무 많이 만들어서 사이트 규모가 커질수록 불편이 많습니다. 라이믹스에서는 불가피한 경우(컴파일된 템플릿이나 CSS, JS 압축/합치기 결과물)를 제외하면 현재 사용하고 있는 모든 캐시파일을 오브젝트 캐시로 통합하는 것이 목표입니다.

  • profile profile
    아하, 알겠습니다!!
  • profile ?
    답변 감사드립니다^^

    like 검색을 하니 되긴한데 속도가 정말 느려지네요...ㅠㅠ

    프리미엄 이 빠질때도 있지만 있을땐 항상 앞에 위치합니다.
    이런 경우도 앞에 % 떼고 해도 될까요?
  • ? profile
    해당 컬럼에 인덱스가 걸려 있고, 프리미엄 외의 다른 것을 검색할 필요가 없다면 그렇게 하셔도 무방합니다.