2014-09-12 3 views
0

내가 내 목적을 설명하자, 나는 차량 예약 응용 프로그램을 어디서 방문자가 그의 여행의 시작 날짜와 종료 날짜를 추가 할 것입니다, 거기에 가용성 목록에있는 드라이버 목록이 있습니다 available_from_date 및 available_to_date)은 작동하는 동안 지속되며, 작동하지 않는 특정 날짜의 exclude_dates 필드가 있습니다. 응용 프로그램은 사용자가 입력 한 여행 날짜 동안 사용할 수있는 차량 목록을 찾아야합니다. 예를 들어 사용자가 13th 9 월 2014-17 9 월 2014 동안 장소 A에서 B로 이동하기를 원하면 데이터베이스는이 기간 동안 사용 가능한 택시 목록을 반환해야하며이 기간 내에 제외 날짜가 없어야합니다 .선택 쿼리 mysql 저장된 함수를 사용하여

이제 테이블에 쉼표로 구분 된 형식으로 exclude_dates를 저장했습니다. 별도의 테이블을 만들었지 만 쿼리를 실행하는 데 더 많은 시간이 걸릴 수 있습니다. mysql 함수를 만들려고했습니다. 실제 검색 쿼리 내에서 호출되며 기간에 제외 된 날짜가있는 경우 true를 반환하고 그렇지 않은 경우 false를 반환합니다.

이 내가

SELECT id, exclude_dates 
FROM `taxi_route` 
WHERE status = 1 
    AND `to_city` = 'Surat' 
    AND `from_city` = 'Ahmedabad' 
    AND `trip_type` = 2 
    AND `available_from_date` <= '2014-09-13' 
    AND available_to_date >= '2014-09-17' 
    AND STR_TO_DATE((SELECT `split`(exclude_dates, ',', 1)),'%d-%m-%Y') 
     NOT BETWEEN STR_TO_DATE('13-09-2014','%d-%m-%Y') 
       AND STR_TO_DATE('17-09-2014','%d-%m-%Y') 

분할을 작성한 쿼리는

DELIMITER $$ 

CREATE FUNCTION split(str VARCHAR(500), delchar VARCHAR(2), x INT) 
RETURNS VARCHAR(500) 
BEGIN 
RETURN SUBSTR(SUBSTRING_INDEX(str, delchar, x), 
LENGTH(SUBSTRING_INDEX(str, delchar, x-1))+IF(x > 1, 2, 1)); 
END$$ 

DELIMITER ; 

이 난만큼 지금까지 잘 작동 내가 쉼표 형식으로 현재 날짜를 분리하는 MySQL의에서 만든 함수입니다 split (exclude_dates, ',', 1)에서 1을 전달하지만 exclude_dates에 날짜가 하나 이상있는 경우 작동하지 않습니다 누군가가 제안하거나 안내 할 수 있습니다. 어떻게 수행 할 수 있습니까? 데이터베이스 스냅 샷은 http://i.imgur.com/JaI8MSx.png

+0

중지 -> 'STR 안녕 _Kermit, 의견을 주셔서 감사하지만 우리는 유효한 날짜 형식으로 또한 사용자가 주어진 문자열을 변환해야합니다 exclude_dates는 varchar이고 우리가 그것을 밖으로 날짜를 추출 할 때 문자열이 될 것이라고() ' – Kermit

+0

@ 다시 날짜 형식으로 변환해야합니까? –

+0

날짜를 문자열로 저장하면 안됩니다. – Kermit

답변

0

exclusion dates에 대한 별도의 테이블을 정의하는 것보다 실행하는 데 더 많은 시간이 소요될 가능성이 큽니다. 검색 목적으로 쉼표로 분리 된 목록을 열에 사용하는 것은 좋지 않습니다. 이것은 정규화 규칙에 대한 것입니다.

테이블을 별도로 정의해야합니다 (예 : 택시, 택시 _ 경로, 택시 _ 경로 _ 제외, 경로 _ 제외). 나중에 더 효율적인 검색을 위해 필요한 색인을 추가해야합니다.

예 :

 
taxi_route 
------------------- 
id 
taxi_id 
available_from_date 
available_to_date 
from_city 
to_city 
 
route_exclusion 
--------------- 
id 
taxi_id 
exclusion_date 

 
taxi 
--------- 
id 
country 
*** 
*** 
*** 
또한 대다 관계를 나타내는 테이블 route_exclusion taxi_route과의 관계 테이블을 추가한다. 나중에 외래 키를 테이블에 지정하여 taxi_routeroute_exclusion 테이블을 가리 킵니다. > taxi.id
  • taxi_route_route_exclusion.taxi_route_id - -> taxi_route.id
  • taxi_route_route_exclusion.route_exclusion_id -> route_exclusion

    • taxi_route.taxi_id :
       
      taxi_route_route_exclusion 
      -------------------------- 
      taxi_route_id 
      route_eclusion_id 
      

      처럼 외부 키를 정의합니다.

      • 택시 : IX1 (상태, trip_type)
      • taxi_route : IX1 (to_city, from_city, available_from_date, available_to_date)

      귀하의 최종 쿼리해야 ID

    같은 인덱스를 정의 모양은 다음과 같습니다.

    SELECT tr.id, re.exclusion_date 
    FROM `taxi_route` tr JOIN `taxi_route_route_exclusion` trre 
        ON tr.id = trre.taxi_route_id 
    JOIN `route_exclusion` re 
        ON re.id = trre.route_exclusion_id 
    JOIN `taxi` t 
        ON t.id = tr.id 
    WHERE 
        t.status = 1 
        AND t.trip_type = 2 
        AND tr.to_city = 'Surat' 
        AND tr.from_city = 'Ahmedabad' 
        AND tr.available_from_date <= '2014-09-13' 
        AND tr.available_to_date >= '2014-09-17' 
    
  • +0

    hello @oardic, 설명 해 주셔서 감사합니다.하지만 저장 프로 시저 또는 함수가 mysql에서 훨씬 빨리 수행되고 조인 될 것이라고 생각합니다. 수천 개의 이러한 레코드가있을 수 있으며 조인을 사용하는 각각의 많은 exclude_date가 많은 시간을 소비합니다. 메모리 대신 오히려 저장 프로 시저는 예 또는 아니오의 형태로 결과를 반환 할 것입니다. 우리는 일반적인 선택 쿼리를 사용할 수 있습니다.이 쿼리는 여행 사이에 제외 된 날짜가 있는지 확인합니다. [내가 틀렸다면 나를 바로 잡으십시오.] –

    +0

    함수를 사용하면 반환 된 각 레코드에 대해 함수를 호출하게됩니다. 쿼리에 따라 결과가 SQL 결합보다 훨씬 느려지므로 결과가 좋지 않을 수 있습니다. 게다가 조인은 함수보다 훨씬 명확합니다. 함수를 사용하지 않고 단일 문으로 쿼리를 작성할 수 있다면 쿼리를보다 쉽게 ​​읽을 수 있습니다. 저장 프로 시저를 사용하는 것은 다른 것입니다. 저장 프로 시저를 정의하고 위 쿼리를 정의 내에 작성할 수 있습니다. 성능 문제는 인덱스 사용을 고려하십시오. – oardic

    +0

    Hello @ eleic 안녕하십니까, taxi_route_excluded_dates의 새 거래 테이블을 추가하여 제안을 구현하려고했지만 제외 된 날짜가 경로 자체와 관련하여 추가되었으므로 다른 route_exclusion 테이블을 가질 수 없습니다. 예를 들어 운전사 D가 장소 A에서 장소 B까지 매월 1 일에서 10 시까 지 운영된다고 말하면 그는 장소 B에서 C까지 11에서 20까지, X에서 Y까지 21에서 30까지 작동하지만, 그는 5 일에 일하고 있지 않습니다. 15 일과 25 일의 날짜가 있기 때문에 시스템에서 택시를 표시해서는 안됩니다. 누군가가 제외 된 날짜 또는 시간에 여행을 계획한다면. –