Q&A

  • Daabase의 고수님께 여쭤보고 싶어요 긴 장문이지만 꼭 읽어봐 주시고 답변을 주셨으면
고수님 안녕하세요.



현재 Delphi5와 Interbase6을 사용하고 있습니다.

제가 이번에 맡고 있는 Project에 관하여 고수님께 몇가지 여쭤보고 싶어 이렇게

글을 뛰웁니다.

저의 짧은 지식으로 여쭙는 것이니 너그러이 봐 주셨으면 합니다.



현재 고민중인 Table에 관한 것인데...

Table의 구조가 다음과 같습니다.



CREATE TABLE T31 (

YYYY VARCHAR(4) not null, // 년도(Key)

BCOD VARCHAR(7) not null, // 거래선코드(Key)

MCOD VARCHAR(7) not null, // 상품코드(Key)

MA01 DOUBLE PRECISION Default 0, // 1월 판매금액

MQ01 DOUBLE PRECISION Default 0, // 판매수량

MA02 DOUBLE PRECISION Default 0, // 2월 판매금액

MQ02 DOUBLE PRECISION Default 0, // 판매수량

MA03 DOUBLE PRECISION Default 0, // 3월 판매금액

MQ03 DOUBLE PRECISION Default 0, // 판매수량

MA04 DOUBLE PRECISION Default 0, // 4월 판매금액

MQ04 DOUBLE PRECISION Default 0, // 판매수량

MA05 DOUBLE PRECISION Default 0, // 5월 판매금액

MQ05 DOUBLE PRECISION Default 0, // 판매수량

MA06 DOUBLE PRECISION Default 0, // 6월 판매금액

MQ06 DOUBLE PRECISION Default 0, // 판매수량

MA07 DOUBLE PRECISION Default 0, // 7월 판매금액

MQ07 DOUBLE PRECISION Default 0, // 판매수량

MA08 DOUBLE PRECISION Default 0, // 8월 판매금액

MQ08 DOUBLE PRECISION Default 0, // 판매수량

MA09 DOUBLE PRECISION Default 0, // 9월 판매금액

MQ09 DOUBLE PRECISION Default 0, // 판매수량

MA10 DOUBLE PRECISION Default 0, // 10월 판매금액

MQ10 DOUBLE PRECISION Default 0, // 판매수량

MA11 DOUBLE PRECISION Default 0, // 11월 판매금액

MQ11 DOUBLE PRECISION Default 0, // 판매수량

MA12 DOUBLE PRECISION Default 0, // 12월 판매금액

MQ12 DOUBLE PRECISION Default 0, // 판매수량

Constraint T31Key Primary Key (YYYY, BCOD, MCOD)

);



위의 구조와 같이 Table을 설계하여 각 년도와 월별 자료를 집계하고 산출해 낼려고

합니다. 하지만 위의 구조를 이용하여 각 월별로 전월과 대비하여 (%)로 그 대배를

산출해 낼려고 할때 적은 양의 Data가 있을경우는 각 Record별로 한건씩 Read하여

전월과 당월의 대비를 (%)로 산출해 내는데 어려움이 없으나 Data의 양이 엄청난 경우

많은 시간을 소비하게 되더군요.

전 그 산출 방법을 다음과 같이 이용하고 있습니다.

먼저 Query문을 이용하여 각 자료를 Group화 하여 자료를 생성합니다.

둘째로 만들어진 Query문을 while문을 이용하여 한건씩 Read하여 대비율을 산출하여

Work 용 Temp을 만들어 그 곳에 다시 저장합니다. (Temp 파일이죠...)

셋째 새로이 만들어진 Temp File을 일반 화면이나 Print 출력을 위한 용도로 활용

하고 있습니다.



하지만 위의 방법을 이용하는데 제약은 시간입니다. 데이타의 양이 너무나도 많아요

각 년도별로 거래처의 수가 약 25,000군데 이며 상품은 약 60,000가지가 넘어요

(5년) * (거래처:25,000군데) * (상품:60,000가지)



이를 Query문으로 모두 처리하고자 하면 제가 만든 Record를 로선 현재년도의 1월과

전년도 12월간의 자료를 동시에 읽을수가 없어 그 대비율을 낼수가 없어요.



고수님들 이런 경우 어떻게 해야 하나요?

Table설계를 다시해도 무관하니 어떻게 해결방안을 제시해 주시면 고맙겠습니다.



6  COMMENTS
  • Profile
    미남과암야수 2001.02.21 21:28
    저는 오라클 밖에 사용을 못해서여...(오라클의경우 예제를 올립니다...)



    저는 아래와 같이 하겠습니다...



    CREATE TABLE T31

    (

    YYYY VARCHAR2(4) not null, // 년도(Key)

    MM VARCHAR2(2) not null, // 월(Key)

    DD VARCHAR2(2) not null, // 일(Key)

    BCOD VARCHAR2(7) not null, // 거래선코드(Key)

    MCOD VARCHAR2(7) not null, // 상품코드(Key)

    MA NUMBER(13, 0), // 판매금액

    MQ NUMBER(13, 0) // 판매수량

    );



    Primary Key는 YYYY, MM, DD, BCOD, MCOD



    뷰를 만든다...(집계 - 월별)



    -- 아래의 문장을 적당히 수정하심 년도별, 년도/월별등 각종 집계가 가능합니다...

    -- 월별 집계

    CREATE OR REPLACE VIE V_T31 AS

    SELECT YYYY, BCOD, MCOD,

    SUM(DECODE(MM, '01', MA, 0)) MA01,

    SUM(DECODE(MQ, '01', MA, 0)) MQ01,

    SUM(DECODE(MM, '02', MA, 0)) MA02,

    SUM(DECODE(MQ, '02', MA, 0)) MQ02,

    SUM(DECODE(MM, '03', MA, 0)) MA03,

    SUM(DECODE(MQ, '03', MA, 0)) MQ03,

    SUM(DECODE(MM, '04', MA, 0)) MA04,

    SUM(DECODE(MQ, '04', MA, 0)) MQ04,

    SUM(DECODE(MM, '05', MA, 0)) MA05,

    SUM(DECODE(MQ, '05', MA, 0)) MQ05,

    SUM(DECODE(MM, '06', MA, 0)) MA06,

    SUM(DECODE(MQ, '06', MA, 0)) MQ06,

    SUM(DECODE(MM, '07', MA, 0)) MA07,

    SUM(DECODE(MQ, '07', MA, 0)) MQ07,

    SUM(DECODE(MM, '08', MA, 0)) MA08,

    SUM(DECODE(MQ, '08', MA, 0)) MQ08,

    SUM(DECODE(MM, '09', MA, 0)) MA09,

    SUM(DECODE(MQ, '09', MA, 0)) MQ09,

    SUM(DECODE(MM, '10', MA, 0)) MA10,

    SUM(DECODE(MQ, '10', MA, 0)) MQ10,

    SUM(DECODE(MM, '11', MA, 0)) MA11,

    SUM(DECODE(MQ, '11', MA, 0)) MQ11,

    SUM(DECODE(MM, '12', MA, 0)) MA12,

    SUM(DECODE(MQ, '12', MA, 0)) MQ12

    FROM T31

    -- WHERE YYYY = '2001' -- 조건을 달면 2001년도 것만....

    GROUP BY YYYY, BCOD, MCOD



    건강하시구요, 행복하세여.. 그럼 1000 * 20...

  • Profile
    궁금증 2001.02.21 23:26
    미남과암야수님 답변에 감사드립니다.

    님께서는 오라클을 사용하신다니 우선 그 것에 관하여 재차 질문을 드리고자 합니다.

    전 오라클을 사용하지 못해봐서 다소 질문 내용이 틀릴수도 있으니 너그러이 봐

    주시면서 조심스럽게 여쭤보도록 하겠습니다.

    먼저 님께서 설계하신 Table 구조까지는 저도 이해를 할 수 있을것 같습니다.

    > CREATE TABLE T31

    > (

    > YYYY VARCHAR2(4) not null, // 년도(Key)

    > MM VARCHAR2(2) not null, // 월(Key)

    > DD VARCHAR2(2) not null, // 일(Key)

    > BCOD VARCHAR2(7) not null, // 거래선코드(Key)

    > MCOD VARCHAR2(7) not null, // 상품코드(Key)

    > MA NUMBER(13, 0), // 판매금액

    > MQ NUMBER(13, 0) // 판매수량

    > );

    > Primary Key는 YYYY, MM, DD, BCOD, MCOD



    그 다음 님께서는 뷰를 만든다고 하셨는데 전 아직 뷰를 전혀 알지 못하고 있습니다.

    뷰의 쓰임새와 그 활용도라든지... 등등....

    참고로 제가 설명을 빠뜨린 부분이 있어 참고 하시면 조금이라도 더 도움이 될것

    같아서 첨부 하겠습니다.

    우선 데이타 양이 많지만 이 데이타는 계속 적인 입력, 수정이 발생하는게 아니고

    매월 1회 데이타를 Update합니다. 매일 매일 자료의 발생이 일어 나지만 월별로 취합

    하여 해당월에 단 한번 Update를 합니다.

    님께서 만드신 TablE 구조로 현재의 모든 데이타를 올린후에 님이 만드신 뷰를 활용

    한다는 것이 맞는 말인지... 아님 저의 짧은 생각으로 님의 뷰는 데이타의 입/출력이

    빈번히 일어 날때마다 자동 발생을 하는 것인지... 제가 뷰를 몰라 드리는 말입니다.

    아울러 님의 뷰를 보면 년(yyyy)/거래선(bcod)/상품(mcod)을 Group화 하여 집계하고

    있는것으로 보아 만일 월별 자료 또한 보고자 한다면 동일한 구조의 월별 자료도 간직

    하고 있어야 하는것으로 보입니다.(거듭 말하지만 전 뷰를 몰라서 여쭤 보는것입니다.)

    제 말이 맞다면 데이타의 양 또한 그만큼 더욱드 늘어 날 것으로 보이는 군요.

    그리고 한가지 더 첨부 한다면

    각 집계된 자료를 가지고.. 예를 들어서

    년/거래선/상품을 기준으로 볼때

    해당 년도의 총 금액을 100%로 볼때 거래선별 총금액과 비교하여 그 대비율을 산출

    해야하며 도한 거래선별 총금액을 100%로 볼때 상품별 총금액 역시 그 대비율을 산출

    해야 합니다. 이렇게 되다 보니 어떻게 해야 빠른 시간내에 원하는 자료를 추출해

    낼수 있을지 무지 힘들군요.

    전 각 산출 자료를 미리 예상하여 만들어 보려 하지만 이 문제는 전월과 대비하여

    그 대비율을 산출하는 부분에서 또한 막히는 군요....



    다음은 예시로 보여주는 것입니다.

    2000년 12월(100,000-100%)/A-거래선(40,000-40%)/1-상품(10,000-25%)

    2-상품(30,000-75%)

    B-거래선(20,000-29%)/1-상품(15,000-75%)

    3-상품( 5,000-25%)

    2001년 01월( 50,000-100%)/A-거래선(20,000-40%)/2-상품(10,000-50%)

    3-상품(10,000-50%)

    B-거래선(30,000-60%)/1-상품( 3,000-10%)

    2-상품(27,000-90%)

    이를 기준으로 볼때

    2000년 12월과 2001년 01월의 대비는 -50%가 되죠.

    그리고 2000년 12월 A-거래선과 2001년 01월의 대비는 0%가 되죠.

    이런식으로 그 대비율을 산출해 내는데 여기서 A-거래선만 검색하여 보고자 한다면...

    무지 복잡하죠. (꾸벅... 죄송....)

    이런식의 자료를 구성해야 하니 자료의 검색및 산출에 많은 시간을 들이지 않고

    해결을 볼수 있는 탁월한 해결책이...

    너무 힘든 일인것 같지만 님께서 도와 주시면 정말 고맙겠습니다.



    너무 긴 설명이 된것 같으며 힘든 질문 같아서 정말 죄송하기 이를때가 없습니다.

    계약된 시간은 이미 넘어섰지만 아직 해결을 짓지 못하고 있는 실정이라 이렇게 늦게

    나마 고수님들과 님과 같은 분에게 질문을 드려 봅니다.

    어떻게 해서든 일은 끝내야 하지만 자료의 검색이나 산출을 하는데 꼬박 일주일정도

    소비가 되니 정말 이건 프로그램이 아니다라고 저 스스로 생각해 봅니다.

    어쩔수 없는 현실이지만 너무도 힘드니 제발 도움을 부탁드립니다.

  • Profile
    미남과암야수 2001.02.22 00:43
    그 심정(피가 마르는) 저두 이해합니다...

    아마 모든 개발자들이 시간에
  • Profile
    미남과암야수 2001.02.21 21:30
    CREATE OR REPLACE VIE V_T31 AS

    SELECT YYYY, BCOD, MCOD,

    SUM(DECODE(MM, '01', MA, 0)) MA01,

    SUM(DECODE(MM, '01', MA, 0)) MQ01,

    SUM(DECODE(MM, '02', MA, 0)) MA02,

    SUM(DECODE(MM, '02', MA, 0)) MQ02,

    SUM(DECODE(MM, '03', MA, 0)) MA03,

    SUM(DECODE(MM, '03', MA, 0)) MQ03,

    SUM(DECODE(MM, '04', MA, 0)) MA04,

    SUM(DECODE(MM, '04', MA, 0)) MQ04,

    SUM(DECODE(MM, '05', MA, 0)) MA05,

    SUM(DECODE(MM, '05', MA, 0)) MQ05,

    SUM(DECODE(MM, '06', MA, 0)) MA06,

    SUM(DECODE(MM, '06', MA, 0)) MQ06,

    SUM(DECODE(MM, '07', MA, 0)) MA07,

    SUM(DECODE(MM, '07', MA, 0)) MQ07,

    SUM(DECODE(MM, '08', MA, 0)) MA08,

    SUM(DECODE(MM, '08', MA, 0)) MQ08,

    SUM(DECODE(MM, '09', MA, 0)) MA09,

    SUM(DECODE(MM, '09', MA, 0)) MQ09,

    SUM(DECODE(MM, '10', MA, 0)) MA10,

    SUM(DECODE(MM, '10', MA, 0)) MQ10,

    SUM(DECODE(MM, '11', MA, 0)) MA11,

    SUM(DECODE(MM, '11', MA, 0)) MQ11,

    SUM(DECODE(MM, '12', MA, 0)) MA12,

    SUM(DECODE(MM, '12', MA, 0)) MQ12

    FROM T31

    -- WHERE YYYY = '2001' -- 조건을 달면 2001년도 것만....

    GROUP BY YYYY, BCOD, MCOD



  • Profile
    권민호 2001.02.21 19:42
    궁금증 wrote:

    > 고수님 안녕하세요.

    >

    > 현재 Delphi5와 Interbase6을 사용하고 있습니다.

    > 제가 이번에 맡고 있는 Project에 관하여 고수님께 몇가지 여쭤보고 싶어 이렇게

    > 글을 뛰웁니다.

    > 저의 짧은 지식으로 여쭙는 것이니 너그러이 봐 주셨으면 합니다.

    >

    > 현재 고민중인 Table에 관한 것인데...

    > Table의 구조가 다음과 같습니다.

    >

    > CREATE TABLE T31 (

    > YYYY VARCHAR(4) not null, // 년도(Key)

    > BCOD VARCHAR(7) not null, // 거래선코드(Key)

    > MCOD VARCHAR(7) not null, // 상품코드(Key)

    > MA01 DOUBLE PRECISION Default 0, // 1월 판매금액

    > MQ01 DOUBLE PRECISION Default 0, // 판매수량

    > MA02 DOUBLE PRECISION Default 0, // 2월 판매금액

    > MQ02 DOUBLE PRECISION Default 0, // 판매수량

    > MA03 DOUBLE PRECISION Default 0, // 3월 판매금액

    > MQ03 DOUBLE PRECISION Default 0, // 판매수량

    > MA04 DOUBLE PRECISION Default 0, // 4월 판매금액

    > MQ04 DOUBLE PRECISION Default 0, // 판매수량

    > MA05 DOUBLE PRECISION Default 0, // 5월 판매금액

    > MQ05 DOUBLE PRECISION Default 0, // 판매수량

    > MA06 DOUBLE PRECISION Default 0, // 6월 판매금액

    > MQ06 DOUBLE PRECISION Default 0, // 판매수량

    > MA07 DOUBLE PRECISION Default 0, // 7월 판매금액

    > MQ07 DOUBLE PRECISION Default 0, // 판매수량

    > MA08 DOUBLE PRECISION Default 0, // 8월 판매금액

    > MQ08 DOUBLE PRECISION Default 0, // 판매수량

    > MA09 DOUBLE PRECISION Default 0, // 9월 판매금액

    > MQ09 DOUBLE PRECISION Default 0, // 판매수량

    > MA10 DOUBLE PRECISION Default 0, // 10월 판매금액

    > MQ10 DOUBLE PRECISION Default 0, // 판매수량

    > MA11 DOUBLE PRECISION Default 0, // 11월 판매금액

    > MQ11 DOUBLE PRECISION Default 0, // 판매수량

    > MA12 DOUBLE PRECISION Default 0, // 12월 판매금액

    > MQ12 DOUBLE PRECISION Default 0, // 판매수량

    > Constraint T31Key Primary Key (YYYY, BCOD, MCOD)

    > );

    >

    > 위의 구조와 같이 Table을 설계하여 각 년도와 월별 자료를 집계하고 산출해 낼려고

    > 합니다. 하지만 위의 구조를 이용하여 각 월별로 전월과 대비하여 (%)로 그 대배를

    > 산출해 낼려고 할때 적은 양의 Data가 있을경우는 각 Record별로 한건씩 Read하여

    > 전월과 당월의 대비를 (%)로 산출해 내는데 어려움이 없으나 Data의 양이 엄청난 경우

    > 많은 시간을 소비하게 되더군요.

    > 전 그 산출 방법을 다음과 같이 이용하고 있습니다.

    > 먼저 Query문을 이용하여 각 자료를 Group화 하여 자료를 생성합니다.

    > 둘째로 만들어진 Query문을 while문을 이용하여 한건씩 Read하여 대비율을 산출하여

    > Work 용 Temp을 만들어 그 곳에 다시 저장합니다. (Temp 파일이죠...)

    > 셋째 새로이 만들어진 Temp File을 일반 화면이나 Print 출력을 위한 용도로 활용

    > 하고 있습니다.

    >

    > 하지만 위의 방법을 이용하는데 제약은 시간입니다. 데이타의 양이 너무나도 많아요

    > 각 년도별로 거래처의 수가 약 25,000군데 이며 상품은 약 60,000가지가 넘어요

    > (5년) * (거래처:25,000군데) * (상품:60,000가지)

    >

    > 이를 Query문으로 모두 처리하고자 하면 제가 만든 Record를 로선 현재년도의 1월과

    > 전년도 12월간의 자료를 동시에 읽을수가 없어 그 대비율을 낼수가 없어요.

    >

    > 고수님들 이런 경우 어떻게 해야 하나요?

    > Table설계를 다시해도 무관하니 어떻게 해결방안을 제시해 주시면 고맙겠습니다.





    만일 저라면 아래의 테이블을 다음과 같이 설계하였을 겁니다.

    제가 직접 시험을 하지 않아서 확신은 드릴수 없지만 참고 하시길바랍니다.

    일반적으로 레코드건수는 인덱스를 어떻게 구성하여 사용하는가에 따라

    속도가 좌우된다고 봅니다.



    만일 년월별로 많은 쿼리가 발생한다면.

    CREATE TABLE T31 (

    YYYY VARCHAR(4) not null, // 년도(Key)

    MONTH VARCHAR(2) NOT NULL, //월

    BCOD VARCHAR(7) not null, // 거래선코드(Key)

    MCOD VARCHAR(7) not null, // 상품코드(Key)

    MA DOUBLE PRECISION Default 0, // 판매금액

    MQ DOUBLE PRECISION Default 0, // 판매수량

    PRIMARY KEY(YYYY VARCHAR(4), MONTH VARCHAR(2), BCOD VARCHAR(7), MCOD VARCHAR(7));

    * 년월은 한필드로 묶어도 관계업겠죠



    아님 거래선 코드로 많은 쿼리가 발생한다면.

    CREATE TABLE T31 (

    BCOD VARCHAR(7) not null, // 거래선코드(Key)

    YYYY VARCHAR(4) not null, // 년도(Key)

    MONTH VARCHAR(2) NOT NULL, //월

    MCOD VARCHAR(7) not null, // 상품코드(Key)

    MA DOUBLE PRECISION Default 0, // 판매금액

    MQ DOUBLE PRECISION Default 0, // 판매수량

    PRIMARY KEY(BCOD VARCHAR(7), YYYY VARCHAR(4), MONTH VARCHAR(2), MCOD VARCHAR(7));



    또 상품코드로 쿼리가 많이 발생한다면

    CREATE TABLE T31 (

    MCOD VARCHAR(7) not null, // 상품코드(Key)

    YYYY VARCHAR(4) not null, // 년도(Key)

    MONTH VARCHAR(2) NOT NULL, //월

    BCOD VARCHAR(7) not null, // 거래선코드(Key)

    MA DOUBLE PRECISION Default 0, // 판매금액

    MQ DOUBLE PRECISION Default 0, // 판매수량

    PRIMARY KEY(MCOD VARCHAR(7), YYYY VARCHAR(4), MONTH VARCHAR(2), BCOD VARCHAR(7));



    물론 위와 같이 구성하고 구현할 때는 일반적으로 디비그리드보다는

    스트링그리드를 이용하는 것이 편리할겁니다.



    제 경험상 몇천건의 데이타에서 검색하는 것과 몇십만건의 데이타에서 검색하는 속도가

    차이가 별로 없다는 것입니다. 인덱스를 적절하게 이용한다면...



    그리고 더불어 뷰를 활용하는 것도 한가지 방법입니다.

    자주 쓰는 년도의 것만 구축하여 쓰는 것입니다. 훨씬 속도가 좋아질것입니다.



















  • Profile
    하눌 2001.02.21 18:13
    답변이 될런지는 모르겠으나,

    이런경우 집계용테이블을 현재사용하고 있는 (temp테이블 에해당되는) 테이블을 만드신뒤

    월집계테이블에 트리거를 작성해서 실시간으로 년집계테이블로 하면 어떨지...