2014-06-09 5 views
0

I이 데이터 MySQL의 테이블을 가지고문자열 질의 데이터베이스 대 파싱

TempID TempName  TempString 
1   aaa   34:56:23:45:67:55 
2   bbb   12:56:67:45:33:99 

I가 개별 값으로 분할 TempString 요구되는 계산을 수행하고 싶다, 예컨대 34, 56, 23 ... 예를 들면. 가장 좋은 방법은

:

  1. 마 문자열 파이썬에서 구문 분석하고 각 값을 얻기 위해
  2. 별표 TempID

    ValID  TempID  Value 
    1   1   34 
    2   1   56 
    3   1   23 
    4   1   45 
    5   1   67 
    6   1   55 
    7   2   12 
    8   2   56 
    9   2   67 
    

    쿼리에 값을 저장하는 값을 사용하여 임시 ID 및 계산

최선의 방법을 제안합니다.

+0

이들은 두 가지 매우 다른 접근 방식입니다. 세 번째 옵션은'TempString'의 값을 분할하여 같은 테이블의 열을 분리하는 것입니다. – vhu

+1

파이썬 문자열 파싱을하는 것이 가장 좋다. –

+0

@vhu, value count가 다를 수 있으므로 예측할 수 없다. 그래서 같은 테이블에 열을 만드는 것은 좋지 않다. –

답변

1

글쎄, 큰 질문은 의미 론적으로 그 값을 깨뜨리는 것입니까?

데이터베이스 테이블을 디자인 할 때 모든 열의 도메인 정의에 대해 생각할 필요가 있습니다. 한 열의 내부에 저장된 모든 데이터 항목은 원자 적이어야합니다 (분해 할 수 없음). 즉, 열에 저장된 항목은 특정 열에 대해 정의 된 도메인의 요소입니다. 이것은 도메인 무결성 제약 조건이라고 할 수 있습니다 (자세한 내용은 data integrity에 대한 위키 백과 문서 확인).

최종 결정을 내리는 데 도움이되는 간단한 경험적 방법을 사용할 수 있습니다. 저장된 문자열의 일부를 검색 (예 : where 절 내부)에 사용해야 할 필요가 있거나 항상 필요합니다. 그렇다면 문자열을 별도의 테이블 열로 분리하십시오. 그렇지 않으면 파이썬을 사용하여 구문 분석하십시오.

도메인 무결성을 파괴하는 간단한 예는 게시물을 연결하는 별도의 테이블을 갖는 대신 단일 게시물의 모든 태그가 큰 문자열로 결합되어 단 하나의 행에 저장되는 블로그 게시물 저장을위한 테이블을 갖는 것입니다 태그에.

상대적으로 복잡한 값을 하나의 열에 저장할 수있는 확실한 예는 날짜를 저장하는 것입니다. 여러 값으로 구성되어 있지만 연도, 월, 일에 대한 모든 정보가없는 완전한 날짜는 완전하지 않습니다 (원자).

0

두 가지 옵션을 먼저 평가해 봅시다.

옵션 1 :

당신은 문자열로 임시 ID를 검색하고 분할 기능의 당신의 delimiter.The 구문으로 콜론을 분할해야는

str.split(str="", num=string.count(str)). 

기본 구분 기호 공간입니다. 이 방법의 문제점은 python 스크립트에서 각 tempid가 검색 가능한 모든 값을 가리키는 매핑을 만들어야한다는 것입니다.이 접근법의 장점은 데이터베이스의 임시 ID와 같은 중복 데이터를 피할 수 있다는 것입니다. 정규화를 사용할 수도 있지만 데이터를 구성하고 더 잘 구성하십시오.

옵션 2 :

심지어 아니지만 최적의 방법으로 당신의 요구 사항을 구현하는 간단한 방법입니다.

옵션 3 :

를 사용하여 일반 expressions.Check이.

#!/usr/bin/python 
import re 

txt='30:24:33:55:60' 

re1='(\\d)' 
re2='(\\d)' 
re3='.*?' 
re4='(\\d)' 
re5='(\\d)' 
re6='.*?' 
re7='(\\d)' 
re8='(\\d)' 
re9='.*?' 
re10='(\\d)'  
re11='(\\d)'  
re12='.*?' 
re13='(\\d)'  
re14='(\\d)'  

rg = re.compile(re1+re2+re3+re4+re5+re6+re7+re8+re9+re10+re11+re12+re13+re14,re.IGNORECASE|re.DOTALL) 
m = rg.search(txt) 
if m: 
    d1=m.group(1) 
    d2=m.group(2) 
    d3=m.group(3) 
    d4=m.group(4) 
    d5=m.group(5) 
    d6=m.group(6) 
    d7=m.group(7) 
    d8=m.group(8) 
    d9=m.group(9) 
    d10=m.group(10) 
    print "("+d1+")"+"("+d2+")"+"("+d3+")"+"("+d4+")"+"("+d5+")"+"("+d6+")"+"("+d7+")"+"("+d8+")"+"("+d9+")"+"("+d10+")"+"\n" 

Output: (3) (0) (2) (4) (3) (3) (5) (5) (6) (0) 

당신은 괄호를 제거하고 2-2 자리 숫자로 문자열을 분할하고 structure.Constraint 일반 expression.This 쓰기 어렵다 테이블을 변경할 필요가 없습니다 귀하의 queries.Advantage에서 사용할 수있는 것은 최적입니다 목표를 달성하는 방법.

옵션 4 : MySQL의 query.The 문제에

를 사용하여 정규 표현식은 MySQL의 정규 표현식은 POSIX 표준을 사용하고 난 당신이 같은 일부 교체를해야이 표준에 위의 준 정규 표현식을 변환하는 것입니다 // D 숫자 또는 [0-9]와 *? ^와 나에 대한 수치심을 인식하지 못하는 몇 가지 사항이 있지만 이러한 유형의 실행은 특히 색인 생성을 사용할 때 쿼리 성능을 향상시킬 것입니다.

0

두 번째 해결 방법이 가장 좋습니다. 해당 값을 저장하는 추가 테이블을 사용하여 데이터베이스를 표준화하십시오.

여러 개의 열을 사용하면 값 수가 변경 될 때 어려워집니다 (필요한 경우 집계 함수를 쉽게 사용할 수 없게됩니다).

모든 값을 스크립트로 가져 오는 것은 가능하지만 데이터베이스의 힘으로 더 이상 멈추지 않습니다 (계산을 수행하기 전에 반환하는 것처럼 필요한 것보다 훨씬 많은 행을 반환 할 수도 있습니다). 그것은 당신이 그들을 돌려 줄 필요가 있는지를 잘 정의 할 수 있습니다).

데이터베이스의 구분 목록은 통증입니다. 당신은 아마 이와 같은 쿼리를 사용하여 새 테이블에 삽입 할 그것을 나눌 수 그러나 -

SELECT NULL, sometable.TempID, SUBSTRING_INDEX(SUBSTRING_INDEX(sometable.TempString, ':', aCnt), ':'. -1) 
FROM sometable 
CROSS JOIN 
(
    SELECT 1+ units.i + tens.i * 10 AS aCnt 
    FROM 
    (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) units, 
    (SELECT 0 AS i UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) tens 
) sub0 
WHERE aCnt <= (LENGTH(sometable.TempString) - LENGTH(REPLACE(sometable.TempString,':', ''))) 

이 최대 100 개 값하지만 쉽게 확장에 대응합니다.