교수는 관계형 테이블을 정의하는 대신 직렬화 된 Java 객체를 Blob으로 저장하라고했습니다.


21

실제로 올바른 속성을 가진 테이블을 정의하는 대신 교수는 다음과 같이 객체를 id에 매핑 할 수 있다고 말했습니다.

id (int)  |   Serialized Object (blob)
   1               10010110110

나는 이것과 관련된 많은 문제를 볼 수있다. 데이터 중복성, ID를 개별적으로 추적해야 함, 전체 테이블을 메모리로 가져 와서 무언가를 검색해야 함 ** ** Java 코드에서 모델을 변경하려는 경우 더 이상 그 모델에 데이터베이스.

나는 그 모델에 영원히 갇혀 있거나 모델을 변경하기 위해 정말 못생긴 다른 일을해야합니다. **이 모든 것이 나에게 나쁜 형태 인 것 같습니다. 교수님의 의견에 동의하지 않습니까? 내가 생각하지 못한 일을하면 어떤 이점이 있습니까? 내가 맞다면 교수님에게 이것에 대해 말해야합니까? 그는 이것을 학급 전체에 전파하고 있었고, 그런 식으로 프로젝트를 만들었다 고 말했습니다. 두 번째 의견은 좋을 것입니다.

이 과정의 이름은 Software Design 입니다.

교수님은 이것이 최선의 방법이라고 말하지는 않았지만 관계형 테이블을 정의하는 것이 합법적 인 대안이라고 말했습니다.

모델은 어떤 식 으로든 동적이 아닙니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Paul White는 GoFundMonica가

답변:


34
  1. 그 자체로는 나쁜 것이 아닙니다. 적절한 맥락 ( "정확한 요구 사항")없이 "더 나은"것에 대해 논쟁하는 것은 무의미한 실천입니다.

  2. 굵게 표시된 부분이 잘못되었습니다. 이미 직렬화 된 객체를 쉽게 확장하여 새 필드를 추가하고 이전 객체와 완전히 이진 호환 할 수 있습니다. 원래 클래스를 변경하는 대신 단순히 새 클래스를 만들 수도 있습니다.

교수와의 토론은 추상 "더 나은"이 아니라 다른 시나리오에서 "관계형"과 "키-값 저장소"의 장단점에 중점을 두어야합니다. 또는 크리스마스가 추수 감사절보다 우월한 지에 대한 토론을 할 수도 있습니다.

-다른 답변을 읽은 후 편집.

다른 답변 중 하나는 "전문가가 단점보다 큰 경우를 상상하기가 어렵다"고 말하는 것입니다.

전체 토론은 구체적인 문제에 대한 것이어야합니다 (그렇지 않으면 "더 나은"및 "더 나쁜 것"을 정의 할 수도 없습니다). 구체적인 예를 하나 들어 보겠습니다. 완전히 만들어졌지만 가능한 한 많은 세부 사항을 살피려고했습니다.

다른 온라인 게임 (브라우저에서 재생, GWT로 작성 및 자바 스크립트로 크로스 컴파일)의 플레이어 통계를 저장하는 데이터베이스가있는 온라인 게임 사이트가 있다고 가정합니다. 일부 게임은 전략적이고 일부는 액션 게임이고 일부는 플랫 포머입니다. 데이터베이스는 관계형이며 플레이어와 플레이 기록 및 점수를 저장합니다.

언젠가는 추가 요구 사항이 있습니다. 게임 중에 플레이어가 게임 상태를 클라우드에 저장하게하여 나중에 같은 시점에 게임을 다시 시작할 수있게합니다. 말할 필요도없이,이 임시 상태를 저장하는 유일한 이유는 게임으로 돌아 오는 것입니다. 상태 자체는 결코 조사되지 않을 것입니다.

이제 두 가지 기본 선택 사항이 있습니다.

  • 게임은 Java로 작성되었으므로 모델을 쉽게 가져 와서 서버로 보내고 한 줄의 코드로 직렬화하여 한 방울로 저장할 수 있습니다. 테이블은 "saved_games"라고 불리며 플레이어에 대한 외래 키 등이 있습니다. 데이터베이스의 관점에서 볼 때 "저장 게임"은 불투명하고 분리 할 수없는 얼룩입니다.

  • 100 개의 게임마다 별도의 관계형 모델을 만들 수 있습니다 (게임당 수십 개의 테이블이 됨). 예를 들어, 팩맨 만의 경우, 모든 먹지 않은 펠렛의 위치, 보너스, 위치 및 유령의 현재 상태를 저장하는 테이블이 있어야합니다. 누군가 언젠가 게임을 수정하더라도 약간이라도 관계형 모델을 업데이트해야합니다. 또한 각 게임 유형에 대해 데이터베이스에 Java 모델을 작성하고 다시 읽으려면 논리를 구현해야합니다.

Justin Cave의 대답에 따르면 두 번째 옵션을 사용해야한다고 말합니다. 나는 이것이 큰 실수라고 생각합니다.

또한 저스틴 케이브 (Justin Cave)의 인식은 위에서 제시 한 것이 "가장자리"또는 "희귀 한"사례라는 것입니다. 나는 그가 미국의 엔터프라이즈 응용 프로그램뿐만 아니라 세계의 모든 IT 프로젝트의 대표 샘플링을 기반으로 일종의 하드 데이터를 제시 할 수 없다면 그러한 의견을 고전적인 예라고 생각합니다. 바이어스.

실제로 관계형 데이터베이스에서 직렬화 된 Java 객체의 문제는 생각보다 훨씬 깊습니다. 그것은 1NF의 핵심, 즉 속성의 도메인은 무엇입니까? . 이 주제에 정말로 관심이 있다면 CJ Date의 Date on Database : Writings 2000-2006에 훌륭한 기사가 있습니다.


의견은 긴 토론을위한 것이 아닙니다. 이 대화는 채팅 으로 이동 되었습니다 .
Paul White는 GoFundMonica가

22

사람들이 이런 종류의 일을하는 프로젝트를 성공적으로 제공 할 수 있습니까? 불행히도, 그들은 합리적으로 자주 그렇게합니다.

이것이 좋은 접근법입니까? 아뇨. 기본적으로 상대적으로 비싼 데이터베이스를 가져 와서 비교적 느린 파일 시스템으로 전환합니다. 객체를 직렬화 및 직렬화 해제하여 상태를 저장하는 시스템을 실제로 구축하려는 경우 데이터베이스를 사용하는 대신 파일 시스템을 사용할 수도 있습니다.

객체를 데이터베이스에 직렬화하여 데이터를 저장하는 시스템을 구축하면 DBA와 친구가되지 않습니다. 중복 데이터를 저장하게됩니다. 공유 데이터가 업데이트 될 때마다 일부 객체는 새로운 값으로 끝나고 일부 객체는 이전 값으로 끝나는 매우 일관되지 않은 데이터로 끝납니다. 데이터에 대해 모든 종류의보고를 수행하는 것은 불가능합니다. 누구나 데이터와 관련된 모든 작업을 수행하려면 누군가 추가 코드를 작성해야합니다. 대부분의 기업에서는 한 시스템에서 데이터를 추출하여 다른 시스템에로드하거나 여러 프런트 엔드 응용 프로그램에서 보고서를 전달할 수있는보고 시스템을 구축하려는 경우가 많기 때문에 매우 큰 문제입니다. 또한, 지적한 바와 같이 계속해서 문제를 처리해야합니다.

이 방법에는 장점이 있습니까? 첫 번째 버전의 앱을 구현하는 것이 매우 쉽다고 주장 할 수 있습니다. 또한 개발자는 데이터베이스와 올바르게 상호 작용하는 것과 관련된 모든 것을 완전히 무시할 수 있습니다. 이러한 장점이 접근 방식의 수많은 단점보다 많은 경우를 상상하기가 어렵습니다.

이 특정 교수를 다루는 방법에 관해서는 별도의 문제입니다 (이 포럼에서 다루지 않을 수도 있습니다). 만약 교수가 현실 세계에서 프로젝트를 적극적으로 개발하고 있다면, 학생의 접근 방식이 근본적으로 잘못되었다는 주장을 받아 들일 수 없을 것입니다. 교수가 원하는 방식으로 프로젝트를 수행하고 자신 또는 다른 과정에서 데이터를 저장하는 적절한 방법을 배우는 것이 더 좋습니다.


2
당신이 말한 것, 내 2 센트 재사용 성은 모듈 성과 공유에 관한 것입니다. 객체 모델은 객체 공유 및 코드 재사용에 중점을 둡니다. 데이터베이스 모델은 데이터 공유 및 재사용에 중점을 둡니다. 두 모델 모두 완전히 도덕적입니다. 두 모델 모두 완벽하지는 않습니다. 그리고이 둘을 조정하는 것은 매우 어렵습니다.
Walter Mitty

1
나는 이것에 동의하지만, 교수가 무언가를 가르치고 그것에 대해 직면하지 않고 더 좋은 방법이라고 말하는 것을 싫어합니다. 다른 모든 가난한 학생들은 이것이 올바른 방법이라고 생각하고 실제 세계로 들어갈 수업은 어떻습니까?
케빈

확실한. 이 공식은 데이터 인 척하는 대상에 해당합니다. 그것들은 데이터이지만 유용한 데이터는 아닙니다.
Walter Mitty

앱의 v2를 출시하자마자 이점은 거의 항상 사라집니다.
Andy

10

프로젝트가 무엇인지, 어떻게 사용되는지에 대한 설명없이 이러한 종류의 디자인이 합리적인 상황이 있습니다. 이것이 적절한 지 아닌지를 말하기는 어렵습니다.

BLOB를 저장하면 DBA가 당신을 미워할 수 있지만, 많은 경우에 유일한 대안은 테이블을 Entity-attribute-value로 바꾸는 것인데, 이는 DBA로부터 더 많은 증오를 얻는 것입니다. 다른 대안은 비 관계형 데이터베이스, 일반적으로 객체 기반 또는 사전 기반 데이터베이스 또는 문서 지향 데이터베이스를 사용하는 것입니다. 일부 DBA, 특히 관계 만 알고있는 데이터베이스는 훨씬 더 열정적으로 싫어할 것입니다. 비 관계형 데이터베이스에는 처리해야 할 자체 문제가 있지만, 객체 데이터베이스를 사용하여 객체를 저장하면 관계형 시스템에서 쉽게 해결할 수있는 다른 문제가 노출 될 수 있습니다.

내가 생각하지 못한 일을하면 어떤 이점이 있습니까?

직렬화 된 객체를 저장한다는 것은 스키마없는 데이터를 저장할 수 있음을 의미합니다 (이름에도 불구하고 스키마없는 것은 일반적으로 실제로 스키마가 없음을 의미하는 것이 아니라 암시적인 스키마 만 있음을 의미합니다). 개발 시간에 스키마를 미리 정의 할 수없고 문제가있는 기존의 관계형 데이터베이스 설계에 따라 격주로 데이터베이스 스키마를 변경해야하거나 테이블이있는 문제 도메인이 많이 있습니다. 시간의 80 %를 사용하지 않는 열의 80 % 또는 실제로 동일한 데이터를 저장하기 위해 수백 개의 다른 테이블이 있으며, 그 중 어느 것도 좋은 디자인을 나타내지 않습니다. 이 문제의 근본 원인은 일반적으로 비 관계형 문제 도메인을 관계형 데이터베이스에 강제 적용하기 때문입니다.

물론, 사람들이 피할 수없는 고통을 불필요하게 야기하는 것으로 판명되는 EAV, 스키마리스 또는 BLOB 스토어를 사용해야한다고 생각하는 많은 프로젝트가 있습니다. 교수의 추론이 무엇인지 교수와 확실히 논의하고 자신의 주장을 제시해야합니다. 논증을 듣고, 당신이 그에게 동의하게 될 수도 있고 그렇지 않을 수도 있습니다.


7

이전에이 작업을 수행했습니다. 특정 시나리오에서 유용한 기술이지만 사용 된 직렬화 형식에 따라 다릅니다. 이 작업을 수행하면 이전 버전의 모델 (예 : XML)을 직렬화 해제 할 수있는 직렬화 형식을 사용해야합니다.

나는 일반적으로 데이터 형식이 복잡한 관계형 모델로 인해 이점을 제공하지 않는 시나리오 (예 : 비즈니스 요구 사항에 필터링이 필요하지 않은 경우 등)에서 이미 데이터베이스를 사용하고 있습니다. 다른 관계형 데이터). 그러한 경우 중 하나는 사용자 쿼리가있는 응용 프로그램입니다. 관계형 모델에는 조건, 중첩 된 조건 (OR / AND 등 ...), 정렬 옵션 등을 저장하기위한 소수의 테이블이있었습니다. 데이터베이스를 변경해야하는 새로운 기능을 추가해야했습니다. 전체 항목을 단일 쿼리 테이블로 바꾸고 다른 모든 옵션을 나타내는 직렬화 된 얼룩으로 바꿨습니다.

또 다른 경우는 다양한 "작업"을 처리하는 시스템이었습니다. 여러 유형의 작업이 있었고 각 작업마다 다른 매개 변수가 있었으며 해당 매개 변수를 기반으로 작업을 검색 / 필터링 할 수있는 비즈니스 요구 사항이 없었습니다. 이를 관계형 데이터베이스로 저장하면 작업 유형 당 최소 1 개의 새 테이블이 필요하여 새 작업 유형을 추가하기가 어려웠습니다. 대신 매개 변수는 데이터베이스에 Blob으로 저장됩니다. 각 작업 유형은 자체 매개 변수의 직렬화 및 직렬화 해제를 담당합니다.

종종 이와 같은 시나리오를 접하게되는 것은 아니지만, 블롭 데이터를 직렬화하면 많은 노력을 절약하고 응용 프로그램을 유지 관리하기 쉽고 실질적인 단점이없는 위와 같은 상황이 발생합니다.


6

저스틴 케이브 (Justin Cave)는 이것이 중복 데이터로 이어질 수 있다는 것이 맞지만 실제로는 데이터베이스 설계 방식에 달려 있습니다.

전체 객체를 얼룩으로 직렬화하는 방법은 대부분의 사람들이 생각하는 것만 큼 터무니 없습니다. 실제로 일부 응용 프로그램의 경우 /programming//a/12644223/1121352에서 설명한 것처럼 이것이 가장 좋은 디자인 일 수 있습니다 .

실제로 객체를 직렬화하면 적어도 두 가지 이점이 있습니다.

1- 불일치 불일치 줄이기 : 특히 많은 클래스와 사용자 정의 유형을 사용하는 경우 일부 Java 유형은 SQL에서 사용할 수 없으므로 Java 객체에서 SQL로 앞뒤로 변환하는 것은 큰 번거 로움과 모호함을 유발할 수 있습니다.

2- 스키마의 유연성 향상 . 실제로 관계형 스키마는 동일한 구조를 공유하는 데이터에 실제로 유용하지만 단일 클래스 내의 일부 개체가 런타임 조건에 따라 다른 속성을 가질 수있는 경우 관계형 스키마가 워크 플로를 크게 방해 할 수 있습니다.

따라서이 접근법에는 분명히 이점이 있습니다 (적어도이 두 가지이지만 필자가 인용하지 않은 다른 것). 물론 지불해야 할 막대한 비용은 거의 모든 관계형 스키마 이점을 잃는 것입니다.

그러나 데이터베이스를 신중하게 디자인하면 두 가지 이점을 모두 누릴 수 있습니다. 각 개체에 고유 한 특성을 사용하여 관계형 스키마 (예 : 고유 키 열)를 설정 한 다음 개체를 Blob에 저장할 수 있습니다 . 이런 방식으로 객체 속성에 의해 정의 된 고유 식별자가 주어지면 객체를 빠르게 검색 할 수 있으며 중복성을 줄이면서도 충돌 불일치를 없애고 Java 객체의 완전한 유연성을 유지할 수 있습니다.

참고로, 일부 DB 제조업체는 PostSQL 및 PostgreSQL 의 JSON 데이터 유형과 같은 관계형 및 객체 모델을 함께 결합 하여 관계형 열과 마찬가지로 JSON을 직접 처리 할 수 ​​있도록 SQL3 및 OQL (Object (제한된) 오브젝트 지원을 SQL에 추가하기위한 조회 언어).

결국 이것은 관계형 모델과 객체 모델 사이의 디자인과 타협의 문제입니다.

주석을 읽은 후 / EDIT : 물론 데이터를 검색 할 수 있어야하는 경우 ( "조회 가능") 데이터를 Blob으로 저장해서는 안됩니다. 그러나 데이터의 일부 가 검색 가능 하지 않고 일종의 메타 데이터 인 경우이 데이터 부분을 Blob 내부의 객체로 저장하는 것이 좋습니다. 특히이 메타 ​​데이터의 구조가 유연한 경우 객체에서 객체로 변경할 수 있습니다.


5

과거에 내가 한 일에 대한 실제적인 예를 들어 보자.

다중 사용자 응용 프로그램에 대한 모든 데이터가 포함 된 데이터베이스가 있습니다. 데이터베이스에는 액세스 권한이있는 사용자 테이블도 있습니다. 이 데이터는 모두 예상대로 정규화됩니다.

그런 다음 응용 프로그램에서 사용자가 열었던 창과 작업을 기억하여 다음 날 아침에 작업을 시작할 때 상태를 복원 할 수 있도록 요청합니다.

  • 첫째, 이것이 때때로 실패한다면, 그것은 무의미하지 않습니까?

    • 예를 들어, 누군가 새로운 버전의 응용 프로그램을 처음 사용하는 경우 열려있는 창을 잊어 버리므로 무엇을…
  • 따라서 객체가 변경되면 100 % 폴 백이 발생하여 블록을 읽을 수 없습니다.

  • 액세스 제어, 백업 등을 갖춘 중앙 집중식 데이터베이스가 이미 있습니다.
  • 파일을 모든 사용자 시스템이 액세스 할 수있는 일종의 파일 서버에 두거나 이러한 파일을 읽으려면 API를 작성해야하므로 파일에 데이터를 저장하는 비용이 높습니다.

또 다른 시간에 , 우리는 많은 장기 실행 계산을 수행하는 응용 프로그램을 가지고 있었고 사용자는 전원 차단 등이있는 경우 마지막으로 알았던 좋은 지점에서 계산을 다시 시작할 수 있기를 원했습니다. 응용 프로그램은 계산을 다시 시작할 것으로 예상 할 수 있으며, 저장해야하는 많은 개체가 있으므로 데이터를 정규화하는 데 많은 비용이들 것입니다.

데이터베이스가 이미 구축되어 있고 잘 정의 된 정규화 된 응용 프로그램 데이터에 사용되고 있으며 블로그를 저장하는 데 사용하지 않는 실질적인 이유가 없기 때문에 현명하고 빠른 옵션을 선택했습니다.


4

매우 중요한 요소 : Java 직렬화 (하나는 구현하여 활성화 된 것 Serializable) 자체가 매우 잘못된 형식이므로 영구 객체 저장에 실제로 사용해서는 안됩니다.

Java 직렬화의 단점은 다음과 같습니다.

  • 다른 언어에서는 데이터를 읽을 수 없습니다.
  • 직렬화 된 객체의 호환성을 유지하는 것은 쉽지 않습니다. 즉, 클래스에 필드를 추가 (또는 제거)하면 이전 버전의 클래스에서 만든 객체를 읽기가 쉽지 않습니다.
  • 그렇게 빠르지는 않지만 마일리지는 다를 수 있습니다.

따라서 다른 직렬화 형식을 사용하면 멋진 Key-Value 저장소가 생기고 Java 직렬화를 사용하면 혼란스러워집니다.


대답의 사실은 단순히 거짓입니다. 1) 형식이 철저한 사양으로 덮여 있습니다. 2) 필드 추가는 전혀 문제가되지 않으며 형식은 매우 유연합니다. 3) 속도는 실제 데이터에 따라 다르지만 JSON 또는 XML과 같은 형식과 비교할 수 있습니다 (때로는 더 빠르거나 때로는 느리다). 기본적으로 한 줄을 제외하고는 전체 대답이 잘못되었습니다. "데이터를 실제로 다른 언어에서 읽을 수는 없습니다".
fdreger

1
그 외에는 1)대답의 나머지 부분이 IMO 유효합니다. 필드를 추가 / 삭제할 때 (특히 최종 필드를 가질 때) 필요한 deserialisaton을 제어하려면 인터페이스가 어수선 해 보일 수 있으며 필요 readObject하고 더 많은 메소드를 재정의해야합니다 readReplace(최종 필드).
jb.

필드를 추가하고 제거 할 때 메소드를 작성할 필요가 없습니다. 최종 필드에 관해서는-원래의 대답은 전혀 언급하지 않았으며, 그렇지 않은 경우 관련이 없습니다 (문제는 다른 모든 형식에 공통적입니다). 마지막으로, "그것이 빠르지는 않지만 (마일리지가 다를 수 있음)"은 아무 의미가 없습니다. 당신은 단 하나의 사실, 다른 언어에 관한 사실을 가지고 있습니다. 그것은 무언가 "엉망인"이라고 부르기에 매우 약한 기초입니다.
fdreger

1
필드를 추가하기 위해 메소드를 작성할 필요는 없지만 역 직렬화 방법에 영향을 주려면 해당 동작을 지정해야합니다. 진화하는 객체 스키마의 역 직렬화 문제에 대한 참고 문헌을 파헤쳐 볼 것입니다.
jb.

3

이것은 잘 생각 된 답변이있는 흥미로운 스레드입니다. 직렬화 된 객체를 저장하고 검색 할 때의 모든 의미에 정통하지 않고 DBA 팀 또는 개발 팀에 제공 할 수있는 답변을 제공하는 것이 흥미로울 것입니다.

핵심은 현재 및 미래의 요구 사항을 충족하고 향후 지원 작업을 최소화 할 수 있도록 솔루션을 가능한 한 단순하게 유지하는 것입니다. 기능 요구 사항과 비 기능 요구 사항 (예 : 인프라 및 데이터베이스)을 모두 충족해야합니다. 80/20 규칙을 기억하십시오. 비즈니스에서 앱의 중요성과 개발 노력이 무엇인지 이해하십시오.

데이터베이스 공간, 속도 및 메모리에 문제가 없다면 매달리지 마십시오.

DBMS가 승인 된 목록에있는 경우 비용이 적절한 한 솔루션에서 사용할 수 있습니다. 관계형 데이터베이스를 사용하여 간단한 Blob을 저장하는 데 문제가 없습니다. 특히 이것이 단순화 된 경우입니다.

솔루션이 프로토 타입 또는 초기 단계 / 버전이어야하는 경우에는 일을 단순하게 유지하는 데 더 많은 스트레스가 가해집니다. 계획 한 데이터 스키마는 나중에 나중에 확장 할 수 있습니다.

스키마가 자체 포함 된 비즈니스 영역을 다루고 비즈니스 규칙이 엄격한 경우를 제외하고 관계형 데이터베이스는 무결성 또는 일관성을 강제하지 않습니다. 예를 들어 Serialized Object Question에 대한 솔루션은 규칙을 시행하기 위해 사전 / 온톨로지 스타일 저장소를 고려할 수 있습니다.

모든 관계형 데이터베이스가 순수한 관계형 데이터베이스 스키마 (예 : 별표, 공간, 비 관계형 ..)를 사용하지 않는다는 점을 고려할 때 응용 프로그램은 관계형 데이터베이스를 문제와 같이 비 관계형 저장소로 사용할 수 있습니다. 많은 핵심 비즈니스 데이터베이스가이 방식으로 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.