Advertisement

자바가 디비와 사귀기 까지 벌어지는 일들

Software development at Tadpole for DB Tools
Oct. 14, 2017
Advertisement

More Related Content

Slideshows for you(20)

Similar to 자바가 디비와 사귀기 까지 벌어지는 일들(20)

Advertisement

More from cho hyun jong(20)

Recently uploaded(20)

Advertisement

자바가 디비와 사귀기 까지 벌어지는 일들

  1. MySQL 디비에 자바(JDBC)가 접속하면 벌어지는 일들 자바가 디비와 사귀기 까지 벌어지는 일들 테드폴허브 조현종
  2. 목차 • SQL은? • JDBC API는? • JDBC API는 무엇이 있나? • 본격 알아보자
  3. 나는 • 테드폴디비 허브를 만들었고 • 그것으로 뭔가 희망이 가져보려는 개발자 웹 브라우저에서 동작하는 데이터베이스 협업 플렛폼
  4. DB의 언어 SQL • SQL(Structured Query Language)이고 DB의 관리를 위해 만들 어진 언어 • 1970년 초에 IBM의 도널드D. 챔벌린과 레이먼드 F.보이스가 만듬. • DB 스키마 생성과 수정 • DB의 조작제어 • 등을 하지요.
  5. SQL이 없다면? 으악
  6. JDBC API는? • Java에서 DB를 사용에 필요한 표준 인터페이스를 재공 • 표준 인터페이스를 각 DB 밴더들이 구현 한 것이 JDBC Driver • JSR-221(JDBC 4.0)의 스팩 • MySQL Connector/J • Oracle JDBC Driver • PostgreSQL JDBC Driver
  7. JDBC API가 없다면? 으악
  8. 자바에서 디비를 연결하는 기본 코드
  9. JDBC API의 주요 구성요소 이름 내용 DriverManager class Driver interface Connection interface Statement interface ResultSet interface SQLException class http://ecomputernotes.com/servlet/servlet-with-mysql-database/jdbc-api
  10. DriverManager class • DB 연결에 필요한 사항을 관리 • 사용자가 로드(?) 해 놓은 드라이버를 관리 • 사용자가 로드(?) 해 놓은 드라이버를 사용하는 클래스
  11. Driver Interface • 디비를 연결해야하는 실제 구현 클래스 • MySQL의 경우 com.mysql.jdbc.Driver의 부모인 com.mysql.jdbc.NonRegisteringDriver 클래스
  12. Connection interface • 실제 디비에 연결하고 • DB의 메타데이터를 관리합니다. • MySQL은 com.mysql.jdbc.ConnectionImpl
  13. Statement Interface • 디비에 SQL을 실행하고 실행결과 받는다. • MySQL은 com.mysql.jdbc.StatementImpl
  14. ResultSet Interface • 쿼리실행 후 받은 결과 데이터를 처리합니다.
  15. 여기까지만 들으면 행복합니다. • JDBC API 를 구현한 디비의 드라이버 만 쓰면 모두 행복할까요? 표준 인터페이스 대로만 쓰면 다 해결될까요?
  16. JDBC API 인터페이스와 구현 • 인터페이스는 인터페이스일뿐 구현의 책임은 각 밴더사에 있다. • 구현이 안되어 있을수 있다. • 구현이 다를수도 있습니다. • 디비에서 지원을 하지 않을수 있다. • 버그는 당연하다. • 드라이버이다 보니 기본 구현에 버그가 있으면 괴롭다. • 인터페이스에 최신 기술 사항이 반영이 느리다.
  17. 구현이 안되어 있을수 있다 • Apache Hive의 경우 statement.setQueryTimeout(queryTimeOut); statement.setMaxRows(intSelectLimitCnt); 메소드가 구현이 안되어 있습니다. (사실 구현하기도 어중간(?) 합니다)
  18. 구현이 다를수 있습니다. • 쿼리 플랜을 가져올때 MySQL은 explain extended select 문을 PostgreSQL은 EXPLAIN (ANALYZE on, VERBOSE on, COST S on, BUFFERS on, TIMING on) 문을 Cubrid는 ((CUBRIDStatement) pstmt).setQueryInfo(true); 등의 구현으로.
  19. 버그는 당연하다. • getIdentifierQuoteString() • storesLowerCaseIdentifiers() • storesLowerCaseQuotedIdentifiers() • storesMixedCaseIdentifiers() • storesMixedCaseQuotedIdentifiers() • storesUpperCaseIdentifiers() • storesUpperCaseQuotedIdentifiers() https://github.com/hangum/TadpoleForDBTools/issues/412
  20. 버그는 당연하다. • SQLite 3.7.2 SQLiteJDBC native • getIdentifierQuoteString : storesLowerCaseIdentifiers : false storesLowerCaseQuotedIdentifiers : false storesMixedCaseIdentifiers : true storesMixedCaseQuotedIdentifiers : false storesUpperCaseIdentifiers : false storesUpperCaseQuotedIdentifiers : false • 대소문자 중복 불가능 대소문자 이름이 중복될 경우 오류발생 테이블 명 중간에 공백가능(‘, “ 로 설정해 주어야 함)
  21. 버그는 당연하다. • MySQL 5.5.30-MariaDB mariadb-jdbc 1.1 • getIdentifierQuoteString : ` storesLowerCaseIdentifiers : true storesLowerCaseQuotedIdentifiers : true storesMixedCaseIdentifiers : false storesMixedCaseQuotedIdentifiers : false storesUpperCaseIdentifiers : false storesUpperCaseQuotedIdentifiers : false • 공백허용하지 않음. 모두 소문자 처리함. QUOTE로 설정하면 에러(QUOTE는 어디다가 쓰일까?)
  22. 버그는 당연하다. • PostgreSQL 9.2.2 PostgreSQL Native Driver PostgreSQL 9.3 JDBC4 (build 1100) • getIdentifierQuoteString : " storesLowerCaseIdentifiers : true storesLowerCaseQuotedIdentifiers : false storesMixedCaseIdentifiers : false storesMixedCaseQuotedIdentifiers : false storesUpperCaseIdentifiers : false storesUpperCaseQuotedIdentifiers : false • 대소문자 혼용가능. 대문자 이거나, 중간에 공백이 있다면 QUOTE로 묵어주어야 합니다. 설정 값과 실제 동작이 틀리다.
  23. 드라이버 버그는 고치기힘들다. • 위의 버그를 수정하여 풀리퀘스트를 보내 보았습니다. • 머지 되었다가 리버트되기를 몇번째 반복 중입니다.
  24. 인터페이스에 최신 기술 사항이 반영이 느리다? 힘들다? • 요즘 대부분의 디비에서는 JSON을 지원합니다. • java.sql.Type에는 어디에서 JSON이 정의되어 있지않습니다.
  25. • JDBC API 인터페이스와 구현했다고 만능은 아니고… 구현을 책임지는 밴더들에게 있습니다.
  26. 본격 탐험에 앞서 준비물을 살펴보자. • MySQL 5.7.19 • JDBC Driver (JDBC 4.2) • mysql-connector-java-5.1.44-bin.jar • Test java code • Wireshark Network Analyzer 간단한 관계 그림
  27. 자바에서 디비를 연결하는 기본 코드
  28. 구성 • Java DB 연결 코드 -> MySQL 5.8 디비 연결 • Wireshark 로 tcp dump 를 뜬다. • 서로 어떤 메시지를 주고 받는지 살펴본다.
  29. TCP dump 내용 보기 • 디비 연결을 위해 26번의 메시지를 교환합니다.
  30. 확인된 사실 • 자바 명령을 날리면 모든 명령을 커밋합니다. • Connection.commit(); 을 호출하면… 실제 MySQL에서는 execSQL(null, "commit", -1, null, DEFAULT_RESULT_SET_TYPE, DEFAULT_RESULT_SET_CONCURRENCY, false, this.database, nul l, false); 라고 쿼리를 날립니다.
  31. 저는 JDBC 드라이버를 통해 하고싶은 일 • 요즘은 다양한 목적, 형태, 상황에 따른 디비가 나오고있습니다. • 디비가 아니더라도 다양한 데이터를 가진 아이들이 나오고 있 지요. • 이것들을 드라이버를 통해 묶어보고싶습니다. Tadpole JDBC Hub Soon….
  32. 좀더 확장하면 • 누가/언제 데이터를 요청했고, • 요청한 결과는 어떻했고, • 그 결과로 인해 만들어진 분석 데이터는 어떠했다도 남겨 볼수 있지 않을까 합니다.
  33. 참고 • Java JDBC API (https://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/) • JDBC API (http://thatsjavainfo.com/java/jdbc-api/) • MySQL API (https://dev.mysql.com/doc/refman/5.7/en/) • What is JDBC?(http://ecomputernotes.com/servlet/servlet- with-mysql-database/jdbc)

Editor's Notes

  1. 데이터는 대부분 데이터베이스에 있습니다. 자바로 데이터를 다루는 사람은 대부분 jdbc 라 불리는 드라이버 연결자를 통해 데이터를 다루게 됩니다. Jdbc가 어떤 과정을 거쳐 디비와 연결하고 데이터를 가져오게 되는지 살펴 보고자 합니다. 개발자들은 프레임웍 사용하거나 툴을 사용해서 지상 기술을 이용해서 편하게 다루는데, 지하1미터에서는 어떻게 디비에 접근하고 사용하는지 알아보는것도 좋겠다싶습니다 그래서 데이터를 다루는 사람은 조금 깊숙한 곳을 알아보고, 개발자들과의 이해의 폭을 줄이면 좋겠습니다. 또 이 드라이버를 통해 어떤 것을 이루어 낼 수 있는지 살펴보도록 하겠습니다.
  2. SQ
  3. Mysql 에서 데이터 가져올때와 oracle 에서 가져올때가…… 다 틀려… 어떻게해~ ㅠㅠ
  4. 없다면, mysql 에서 데이터 가져올때의 자바 코드와 oracle 에서 데이터 가져올때의 자바 코드가 다 틀려~ 관련 서드파트(커넥션 풀과 프레임웍)들을 디비마다 만들어야 해 ㅠㅠ
  5. 먼저 일반적으로 mysql 디비를 연결하고 select 하는 코드는 다음과 같습니다. Class.forName 이라는 코드를 통해서 mysql 드라이버를 자바 메모리에 로딩하고 DriverManager 통해서 지정된 mysql 디비에 root유저에 tadpole 패스워드로 연결합니다. 위의 코드에서 com.mysql.jdbc.Driver 를 주목해주십시오. 해당 코드를 통해 mysql 드라이버가 자바에 올라가게 됩니다. 그리고 sql을 DB에 전달하기 위해 Statement 객체를 만들고 해당 객체에 디비의 현재 버전과 시간을 묻는 쿼를 실행하고 그 쿼리의 결과를 받아서 결과를 출력해 줍니다. 문제가 생겼을때 에러를 어떻게 처리해야하는지 감싸져 있구요. 여기까지는 별거 없는 듯이 보입니다.
  6. 실제 구성요소는 위와 같은데요 다음의 구성 요소 중에 DriverManager 만 클래스이고 나머지는 다 인터페이스입니다. 즉 누군가가 구현해 주어야 한다는 이야기 입니다. 위의 것들을 구현하면 드라이버라고 표현합니다 . 물런 더 많지만요.
  7. 받은 데이터를 문자로 숫자로 날자로 받고 싶어요.. 데이터를 몇개를 받고 싶어요.
  8. 여기까지만 들으면 행복합니다 물런 대부분은 그렇게 생각할 수도 있습니다.
  9. 지금까지 jdbc api 와 그것을 구현한 mysql 드라이버를 잠깐 살펴봤는데요.
  10. SQL on hadoop 류의 디비에서 몇건의 데이터를 가져올지 않고 지원하고, 몇시간이 걸리는지 예측하기 어렵기 때문입니다.
  11. 올챙이에 타조를 만드신 최현식 박사님이 버그 리토팅을 해오셨습니다. 아래의 메소드는 테이블이나 컬럼이름을 어떻게 처리할지 여부를 알수 있는 메소드 입니다. 그래서 봤는데 제가 JDBC 스펙과 올챙이를 자세히 몰라 이런 이슈를 만들 수 도 있으니 이슈가 유효하지 않더라도 너그럽게 양해 부탁드립니다. 혹시 올챙이에서 quoted identifier를 고려해서 동작하도록 되어 있나요? 예를 들어 CREATE TABLE "Test_Table" (... 이렇게 테이블을 만들면 실제로 Table 이름은 Test_Table 로 upper/lower mixed character들로 저장됩니다. 그런데 올챙이에서 저 테이블을 제거하려고 할 경우 DROP TABLE Test_Table로 제거 하려고 합니다. 이런 경우 Test_Table 은 DB에 쿼리로 들어갈 때 " "가 없기 때문에 oracle의 경우 TEST_TABLE, postgresql 의 경우에는 test_table로 인식하게 됩니다. 이렇게 되면 DB에서는 없는 table로 오류를 내뱉게 됩니다. 일단 Tajo에서 quoted identifier를 이용해 만든 테이블들에서 이런 현상이 일어나는 것을 확인했습니다. 이런 현상이 있다면 다른 DB들도 유사 현상이 있을 것이라 생각이 듭니다. 제 생각에는 JDBC driver의 DatabaseMetaData 객체에 아래 메소드들을 이용하여 DB에 따라 다르게 처리하면 어떨까 제안드려봅니다.
  12. 위의 버그가 있는 것을 확인하여 드라이버 소스를 수정하고 패치를 보냈는데 머지 됐다가 리버트되기를 몇번씩 반복하였습니다. 그래서 생각했죠~ 이미 잘못된 구현체로 구현된 너무 많은 결과 물때문이지 않을까 합니다. 왼쪽은 큰아들 희찬이고, 오른쪽은 저인데.. 왼쪽 아들 상태에서 구현된 결과물이 커버린거죠. 드라이버의 잘못된 것을 고치면 이미구현된 결과물을 버그가… 나올테구요. 라고 상상해봤습니다.
  13. 이것은 아마 xml 의 영향인가도 싶은데요. 그만큼 대중적인지지도가 있어서 어느하나 치우치면 변경되기 힘들기때문에 그러지 않나도 싶습니다. 혹은 업데이트가 느린 요즘 자바 의 영향인가도 싶구요.
  14. JDBC API 인터페이스와 구현
  15. 먼저 일반적으로 mysql 디비를 연결하고 select 하는 코드는 다음과 같습니다. Class.forName 이라는 코드를 통해서 mysql 드라이버를 자바 메모리에 로딩하고 DriverManager 통해서 지정된 mysql 디비에 root유저에 tadpole 패스워드로 연결합니다. 위의 코드에서 com.mysql.jdbc.Driver 를 주목해주십시오. 해당 코드를 통해 mysql 드라이버가 자바에 올라가게 됩니다. 그리고 sql을 DB에 전달하기 위해 Statement 객체를 만들고 해당 객체에 디비의 현재 버전과 시간을 묻는 쿼를 실행하고 그 쿼리의 결과를 받아서 결과를 출력해 줍니다. 문제가 생겼을때 에러를 어떻게 처리해야하는지 감싸져 있구요. 여기까지는 별거 없는 듯이 보입니다.
  16. 요즘처럼 많은 디비가 나오고 다양한 형태의 디비도 나오고 특수 목적의 디비도 나오고 하이브리드 디비도 나오고 드라이버를 통해 이 간격을 매꾸어 보고 싶습니다.
  17. 미련한 자는 힘들때 방황하고 현명한 자는 여행을한다.
Advertisement