[ParkNav] 알고리즘 Version 0 ~ Version 2

Jae Hun Lee·2023년 4월 27일
0

parknav

목록 보기
6/8
post-thumbnail

Version 0


  • 예약
    1. 예약시작시간이 종료시간보다 늦게 입력된 경우 예외처리
      • NOT_END_TO_START(400,"입차시간이 출차시간보다 빨라야 합니다.")
    2. 주차장 ID가 주차장 정보 DB에 없는 경우 예외처리
      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 로그인한 유저의 대표차량이 등록되지 않은 경우 예외처리
      • NOT_FOUND_CAR(400, "등록된 차량이 없습니다.")
    4. 예약시작~종료시간 사이에 동일차량으로 예약한 내역이 있는 경우 예외처리
      • ALREADY_RESERVED(400, "이미 예약된 시간입니다.")
    5. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    6. 현재 주차가능 대수와 선택시간 예약건수 확인
      • 현재 주차가능 대수 : (주차장 총 구획 수) - (현재 주차중인 차량 대수)
      • 선택시간 예약건수 : (선택시간과 겹치는 예약건수) - (예약차량 중 이미 입차한 차량 수)
        • 선택한 시간을 포함하거나 걸치고 있는 예약 건수이며, 예약차량이 이미 입차했다면 예약건수에서 제외한다.
      • (현재주차가능대수 > 선택시간 예약건수) 라면, 예약 가능
      • (현재주차가능대수 <= 선택시간 예약건수) 라면, 예약이 불가하므로 예외처리
        • NOT_PARKING_SPACE(400, "주차할 공간이 없습니다.")
  • 입차
    1. 관리자 로그인한 아이디가 해당 주차장의 관리자가 아닌 경우 예외처리

      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 주차장 ID가 ParkInfo 에 없는 경우 예외처리

      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 입차하려는 차량번호가 주차장에 이미 입차한 차량인 경우 예외처리

      • 주차현황DB(ParkMgtInfo)에서 해당 주차장에서 입차 차량번호로 입차한 차량 중, 마지막으로 입차한 현황 데이터를 가져온다.
      • 현황 데이터가 존재하고 출차정보가 없다면, 이미 입차된 차량이므로 예외처리한다.
      • ALREADY_ENTER_CAR(400, "이미 입차된 차량입니다.")
    4. 해당 주차장에 현재 예약이 되어있는 차량 수 구한다.

      • 해당 주차장의 예약현황과 주차현황을 모두 가져와 예약차량조건에 해당하는 차량 수를 구한다.
      • 이 때, 입차하려는 차가 예약차량조건에 해당한다면 예약차량 카운트에서 제외시킨다.
      ✔️ 예약차량 조건 : (예약 시작 시간 - 1시간) ≤ 현재시간 < 예약 종료 시간 → 예약한 차량이 최대한 입차할 수 있도록 (예약 시작시간 - 1시간)부터 예약차량으로 카운트한다. → 예약차량 중 이미 입차한 차가 있다면 예약된 차량 수에서 제외한다.
    5. 입차 시도한 차량의 예약여부를 확인하여 일반차량 or 예약차량으로 분류한다.

      • 입차하려는 차량이 예약차량조건에 해당한다면, 예약차량으로 분류한다.
      • 단, 예약정보 DB에서 찾은 데이터의 출차시간이 있다면 해당 예약내역을 이미 사용한 것이므로 일반차량으로 분류한다.
    6. 4번에서 구한 현재 예약 차량 수와 현재 입차한 차량 수를 합하여 총 구획 수와 비교한다.

      • (예약 차량 수 + 현재 주차중인 차량 수 < 총 구획 수) 라면, 입차 가능
      • (예약 차량 수 + 현재 주차중인 차량 수 < 총 구획 수) 라면, 입차 불가이므로 예외처리
        • NOT_PARKING_SPACE(400, "주차할 공간이 없습니다.")
  • 출차
    1. 주차장 관리자 아이디의 주차장 ID와 사용자가 입차하는 주차장의 ID가 같지 않다면 예외처리
      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 출차하려는 차량이 주차장에 없는 경우 예외처리
      • NOT_FOUND_CAR(400, "등록된 차량이 없습니다.")
    3. 출차하려는 차량이 이미 주차장을 이용하고 출차했다면 예외처리
      • ALREADY_TAKEN_OUT_CAR(400,"이미 출차된 차량입니다.")
    4. 출차시 요금 계산
      • 입차시간 ~ 현재(출차시간)까지 요금을 계산한다.
    5. 기존 주차현황정보(ParkMgtInfo) 업데이트
      • 요금과 출차시간을 업데이트한다.

Version 0 문제점

  • 예약처리 일관성 부족
    • 예약 가능 여부 기준이 예약하는 현재 시간의 주차가능대수에 따라 달라지므로, 같은 시간대에 예약을 하더라도 예약하는 시점에 따라 예약 성공 여부가 달라진다.
    • ex) A, B 모두 당일 13시~14시 예약을 하려는 상황에서, A가 예약을 시도할 당시 주차장의 빈자리가 없다면 A는 예약 실패하고, B가 예약을 시도할 당시 주차장에 자리가 많다면 B는 성공한다.
  • 예약차량 입차 안정성 보장 불가
    • 현재 시간 주차 가능대수에 따라 예약여부가 결정되므로, 예약 후 입차할 때 주차장 상황에 따라 입차하지 못할 가능성이 높다.
    • ex) 예약 시도할 당시 주차장 자리가 많아 당일 13~14시 예약을 성공했다. 예약시간에 맞춰 입차하려고 할 때 이미 주차장이 만차인 경우는 입차할 수 없다.

해결방안

  • 현재 주차장 빈자리를 기준으로 예약가능여부를 판단하는 것이 아니라, 예약시작시간 ~ 종료시간 사이에 예약한 차량 수를 기준으로 예약가능여부를 정한다.
  • 일반차량과 예약차량이 각각 들어갈 수 있는 구역을 나눈다. 일반차량은 예약차량 구역에 들어갈 수 없으므로 예약차량의 입차 안정성이 올라간다.

Version 1


  • 설정
    • 예약차량 구획 수 : 총 구획 수 / 2
    • 일반차량 구획 수 : 총 구획 수 / 2 ( = 총 구획 수 - 예약차량 구획 수)
  • 예약
    1. 예약시작시간이 종료시간보다 늦게 입력된 경우 예외처리
      • NOT_END_TO_START(400,"입차시간이 출차시간보다 빨라야 합니다.")
    2. 주차장 ID가 주차장 정보 DB에 없는 경우 예외처리
      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 로그인한 유저의 대표차량이 등록되지 않은 경우 예외처리
      • NOT_FOUND_CAR(400, "등록된 차량이 없습니다.")
    4. 예약시작~종료시간 사이에 동일차량으로 예약한 내역이 있는 경우 예외처리
      • ALREADY_RESERVED(400, "이미 예약된 시간입니다.")
    5. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    6. 예약하려는 시간 사이에 다른 차량들이 예약한 건수와 주차장의 예약차량 구획 수를 비교한다.
      • 예약하려는 시간을 한시간 단위로 잘라 그 시간대에 예약되어 있는 건수를 구한다.
      • (예약선택시간에 다른 차량이 예약한 건수) >= (주차장 예약차량 구획 수) 라면, 예약불가 시간대 리스트(notAllowedTimeList)에 추가한다.
      • 예약불가 시간대가 하나도 없어야 예약 가능하다.
      • 예약불가 시간대가 하나 이상 있다면 예약 불가하므로 예외처리한다.
        • NOT_ALLOWED_BOOKING_TIME(400, "예약불가한 시간이 포함되어 있습니다.")
  • 입차
    1. 관리자 로그인한 아이디가 해당 주차장의 관리자가 아닌 경우 예외처리
      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 주차장 ID가 ParkInfo 에 없는 경우 예외처리
      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 입차하려는 차량번호가 주차장에 이미 입차한 차량인 경우 예외처리
      • 주차현황DB(ParkMgtInfo)에서 해당 주차장에서 입차 차량번호로 입차한 차량 중, 마지막으로 입차한 현황 데이터를 가져온다.
      • 현황 데이터가 존재하고 출차정보가 없다면, 이미 입차된 차량이므로 예외처리한다.
      • ALREADY_ENTER_CAR(400, "이미 입차된 차량입니다.")
    4. 주차장의 전체 구획수의 반반씩 일반차량, 예약차량 구역으로 설정한다. (총 구획이 홀수일 경우 일반차량에 1칸을 더 준다)
    5. 해당 주차장에 입차중인 일반차량, 예약차량 개수를 가져온다.
      • 일반차량 : 주차현황 DB에서 출차시간이 null, 예약정보 ID가 null인 경우
      • 예약차량 : 주차현황 DB에서 출차시간이 null, 예약정보 ID가 있는 경우
    6. 입차하려는 차량이 예약차량인지 일반차량인지 확인한다.
      • 예약차량 : 예약정보 DB에서 주차장, 차량번호가 일치하면서, 예약 시작시간 ≤ 현재시간 ≤ 예약 종료시간 에 해당하는 데이터가 있는 경우
      • 일반차량 : 예약차량이 아닌 경우
    7. 예약차량, 일반차량 구획이 남아있는지 검증한다.
      • 예약차량
        • (예약차량 구획 > 입차중인 예약차량 수)일 경우, 입차 가능
        • (예약차량 구획 <= 입차중인 예약차량 수)일 경우, 입차 불가하므로 예외처리
          • NOT_PARKING_SPACE(400, "주차할 공간이 없습니다.")
      • 일반차량
        • (일반차량 구획 > 입차중인 일반차량 수)일 경우, 입차 가능
        • (일반차량 구획 <= 입차중인 일반차량 수)일 경우, 입차 불가하므로 예외처리
          • NOT_PARKING_SPACE(400, "주차할 공간이 없습니다.")
  • 출차
    1. 주차장 관리자 아이디의 주차장 ID와 사용자가 입차하는 주차장의 ID가 같지 않다면 예외처리
      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 출차하려는 차량이 주차장에 없는 경우 예외처리
      • NOT_FOUND_CAR(400, "등록된 차량이 없습니다.")
    3. 출차하려는 차량이 이미 주차장을 이용하고 출차했다면 예외처리
      • ALREADY_TAKEN_OUT_CAR(400,"이미 출차된 차량입니다.")
    4. 출차시 요금 계산
      • 입차시간 ~ 현재(출차시간)까지 요금을 계산한다.
    5. 기존 주차현황정보(ParkMgtInfo) 업데이트
      • 요금과 출차시간을 업데이트한다.

Version 1 개선된 부분

  • 예약처리 일관성 보장
    • 시간대별로 예약된 건수를 기준으로 예약건수가 예약구획보다 적으면 예약이 가능하므로, 일관성 있는 예약처리가 가능하다.
  • 예약차량 입차 안정성 향상
    • 일반구역, 예약구역이 나뉘어져 있으므로, 일반차량 때문에 예약차량이 입차하지 못하는 경우는 발생하지 않는다.

Version 1 문제점

  • 주차장 운영의 비효율성
    • 일반차량 구획이 다 차고, 예약차량 구획은 자리가 남는 경우, 일반차량이 입차를 시도하면 주차장에 빈자리가 있음에도 일반차량 구획이 없으므로 입차할 수 없는 상황이 발생할 수 있다.
    • 특정 시간대의 예약차량 구획이 다 찬 경우, 일반차량 구획 자리가 남는다 하더라도 더 이상 예약할 수 없는 상황이 발생할 수 있다.
  • 예약차량 입차 안정성 개선 필요
    • 예약차량이 입차 후, 예약시간을 넘어서도 출차하지 않은 경우, 다음 시간대 예약차량이 예약구획 자리가 없어 입차를 못하는 경우가 발생할 수 있다.
  • 일반/예약차량 분류 방법 개선 필요
    • 예약 시간 사이에 입차한 차량만 예약차량으로 분류된다. 예약시간보다 10분 일찍 들어와 예약종료시까지 입차한 차량은 일반차량으로 분류된다.
    • ex) 14:00~17:00 예약한 차량이 13:50에 입차하여 17:00까지 주차했다면 13:50~17:00까지 일반차량 입차대수로 카운트 됨과 동시에 예약건수로도 카운트되어 주차장에서 총 2자리를 차지하게 된다.

해결방안

  • 기존 일반차량 구획, 예약차량 구획에서 ‘공통 구획’을 추가한다.
    • ex) 주차장 총 구획 수 : 100대, 일반차량 구획 : 40대, 예약차량 구획 : 40대, 공통 구획 : 20대
  • 일반차량 구획이 만차인 상황에서 일반차량이 입차를 시도할 경우, 공통 구획으로 입차시킨다. 다른 일반차량이 출차할 경우 공통 구획 입차에서 일반차량 입차로 카운트한다.
  • 예약차량이 입차 후, 예약시간을 넘어서도 출차하지 않는 경우, 공통 구획 입차차량으로 카운트한다.
  • 매 시간마다 예약차량 입차대수, 일반차량 입차대수를 카운트하는 스케쥴링을 실행한다.
    • 예약시간 이전에 예약차량이 입차한 경우, 일반차량으로 카운트하고, 예약시간이 되면 예약차량으로 카운트한다.
    • 예약시간에 주차한 경우, 예약차량으로 카운트하고, 예약시간이 지났는데도 주차중이면 공통 구획으로 카운트한다.

Version 1-1




  • 설정
    • 일반차량구역 : 총 구역 수의 40%
    • 예약차량구역 : 총 구역 수의 40%
    • 공통차량구역 : (총 구역 수) - (일반차량구역 + 예약차량구역)
    • 주차관리현황 테이블(park_mgt_info)에 주차 구역을 표시할 zone 컬럼 추가
  • 예약
    1. 예약시작시간이 종료시간보다 늦게 입력된 경우 예외처리
      • NOT_END_TO_START(400,"입차시간이 출차시간보다 빨라야 합니다.")
    2. 주차장 ID가 주차장 정보 DB에 없는 경우 예외처리
      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 로그인한 유저의 대표차량이 등록되지 않은 경우 예외처리
      • NOT_FOUND_CAR(400, "등록된 차량이 없습니다.")
    4. 예약시작~종료시간 사이에 동일차량으로 예약한 내역이 있는 경우 예외처리
      • ALREADY_RESERVED(400, "이미 예약된 시간입니다.")
    5. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    6. 예약하려는 시간 사이에 다른 차량들이 예약한 건수와 주차장의 예약차량 구획 수를 비교한다.
      • 선택사이 시간대별 예약건수를 구한다.
        • 예약건수 = (시간대별 예약되어 있는 건수 - 예약차량 중 이미 출차까지 완료한 차량 수)
        • ex) 13:00~14:00 시간대에 3대가 예약되어 있는데, 3대 중 한 차량이 12:00~14:00 예약 후 13:00에 출차했다면, 13:00~14:00 시간대 예약건수는 총 2대로 계산한다.
      • (예약선택시간에 다른 차량이 예약한 건수) >= (주차장 예약차량 구획 수) 라면, 예약불가 시간대 리스트(notAllowedTimeList)에 추가한다.
      • 예약불가 시간대가 하나도 없어야 예약 가능하다.
      • 예약불가 시간대가 하나 이상 있다면 예약 불가하므로 예외처리한다.
        • NOT_ALLOWED_BOOKING_TIME(400, "예약불가한 시간이 포함되어 있습니다.")
  • 입차
    1. 관리자 로그인한 아이디가 해당 주차장의 관리자가 아닌 경우 예외처리
      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 주차장 ID가 ParkInfo 에 없는 경우 예외처리
      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 입차하려는 차량번호가 주차장에 이미 입차한 차량인 경우 예외처리
      • 주차현황DB(ParkMgtInfo)에서 해당 주차장에서 입차 차량번호로 입차한 차량 중, 마지막으로 입차한 현황 데이터를 가져온다.
      • 현황 데이터가 존재하고 출차정보가 없다면, 이미 입차된 차량이므로 예외처리한다.
      • ALREADY_ENTER_CAR(400, "이미 입차된 차량입니다.")
    4. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    5. 주차장의 일반, 예약, 공통구역 수와 구역별 현재 주차중인 차량 대수를 구한다.
      • 주차장의 일반, 예약, 공통구역 수를 각각 구한다. (getUseSpaceInfo)
        • 일반구역 = 총 구역 수의 40%
        • 예약구역 = 총 구역 수의 40%
        • 공통구역 = (총 구역 수) - (일반구역 + 예약구역)
      • 주차장 구역별 현재 주차중인 차량 대수를 구한다. (getParkSpaceInfo)
        • 주차장 구역별 출차시간이 null인 차량 대수를 구한다.
    6. 입차하려는 차량이 예약차량인지 일반차량인지 확인한다.
      • 예약차량 : 예약정보 DB에서 주차장, 차량번호가 일치하면서, 예약 시작시간 ≤ 현재시간 ≤ 예약 종료시간 에 해당하는 데이터가 있는 경우
      • 일반차량 : 예약차량이 아닌 경우
    7. 예약차량, 일반차량에 따라 구역수와 주차중인 차량 대수를 비교하여 입차처리를 한다.
      • 예약차량
        • 예약차량이나, 예약내역으로 이미 출차까지 한 차량은 입차 시도시 일반차량으로 처리한다.
        • 예약구역에 자리가 없는 경우(예약구역 수 ≤ 예약구역 입차 차량 수) 입차 불가 예외처리
          • NOT_PARKING_BOOKING_SPACE(400, "주차할 공간이 없습니다. - 예약구역")
        • 예약차량이 입차하면 예약시작시간 ~ 예약종료시간 기준으로 계산한 요금을 입차정보에 넣어준다.
        • 입차정보에 구역(zone)은 BOOKING 으로 넣어준다.
      • 일반차량
        • 일반구역에 자리가 있다면(일반구역 수 > 일반구역 입차 차량 수), 구역(zone)은 GENERAL , 금액(charge)은 0원으로 입차정보를 넣어준다.
        • 일반구역에 자리가 없고, 공통구역에 자리가 있다면(공통구역수 > 공통구역 입차 차량 수), 구역(zone)은 COMMON , 금액(charge)은 0원으로 입차정보를 넣어준다.
        • 일반구역, 공통구역 모두 자리가 없다면 입차 불가 예외처리
          • NOT_PARKING_COMMON_SPACE(400, "주차할 공간이 없습니다. - 공통구역")
  • 출차
    1. 주차장 관리자 아이디의 주차장 ID와 사용자가 입차하는 주차장의 ID가 같지 않다면 예외처리
      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 출차하려는 차량이 주차장에 없는 경우 예외처리
      • NOT_FOUND_ENTER_CAR(400, "입차한 차량이 없습니다.")
    3. 출차하려는 차량이 이미 주차장을 이용하고 출차했다면 예외처리
      • ALREADY_TAKEN_OUT_CAR(400,"이미 출차된 차량입니다.")
    4. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    5. 출차하려는 차량이 예약차량인지 일반차량인지 구분한다.
    6. 출차하려는 차량이 예약차량인 경우, 요금을 계산하고 예약종료시간을 출차시간으로 변경한다.
      • 예약종료시간 이전에 출차한 경우, 요금은 예약시작~종료시간으로 계산한다.
      • 예약종료시간 이후에 출차한 경우, 요금은 예약시작~출차시간으로 계산한다.
    7. 출차하려는 차량이 일반차량인 경우, 출차시 공통구역에 일반차량이 있다면, 그 차량을 일반구역으로 옮긴다.
      • 공통구역에 있는 일반차량 중 제일 먼저 들어온 차량을 일반 구역으로 옮긴다.
    8. 기존 주차현황정보(ParkMgtInfo) 업데이트
      • 요금과 출차시간을 업데이트한다.
  • 스케쥴링
    1. 0 시 0분마다 스케쥴링 실행
    2. 일반 구획 → 예약 구획
      • 예약 시작 시간이 현재시간:0분:0초 인 예약건을 모두 가져온다.
      • 예약 건의 차량 번호 중 이미 주차장에 입차 한 차량 정보를 가져온다.
      • 해당 주차장의 예약 구획의 남은 수를 구한다.
        • 예약 구획 수가 남은 경우 : 예약 구획으로 이동한다.
        • 예약 구획 수가 없는 경우 : 이동하지 않는다.
    3. 예약 구획 → 공통 구획
      • 예약 종료 시간이 현재시간 -59분 59초 부터 현재시간:0분:0초 의 예약건을 모두 가져온다.
      • 예약 종료 건중 아직 출차하지 않은 차량의 정보를 가져온다.
      • 해당 주차장의 공통 구획의 남은 수를 구한다.
        • 공통 구획 수가 남은 경우 : 공통 구획으로 이동한다.
        • 공통 구획 수가 없는 경우 : 이동하지 않는다.

Version 1-1 개선된 부분

  • 주차장 운영 효율성 일부 개선
    • 공통 구역을 추가하여, 일반구역이 다 찬 경우에도 공통구역 자리가 있다면 입차할 수 있다.
  • 예약차량 입차 안정성 개선
    • 예약차량이 예약종료 시간 후에도 나가지 않는 경우, 공통구역으로 옮겨지기 때문에 해당 예약시간에 예약한 다른 예약차량들은 입차가 가능하다.
  • 일반/예약차량 유동적 구역 이동 가능
    • 매 시간 스케쥴링을 통해 일반구역, 예약구역, 공통구역에 들어가야 할 차량들이 적절하게 배치된다.

Version 1-1 문제점

  • 주차장 운영 효율성 미흡
    • 일반, 예약, 공통 구역이 나뉘어져 있기 때문에, 일반차량이 많은 경우, 예약차량이 많은 경우 등 특정 차량이 많은 경우 주차장에 빈자리가 있음에도 입차, 예약이 불가한 상황들이 발생한다.
  • 예약가능여부 확인 로직 성능 개선 필요
    • 매시간마다 예약이 가능한지 확인해야하기 때문에 예약시간이 길어질수록 실행되는 쿼리 개수가 많아져 성능이 저하된다.
  • 예약차량 입차 안정성이 보장되지 않는 상황 발생
    • 공통구역에 차량이 가득 찬 경우, 예약종료 시간 후에도 나가지 않는 예약차량은 공통 구역으로 옮길 수 없고, 다음 시간대에 예약한 차량이 입차불가한 상황이 발생한다.

해결방안

  • 기존 예약, 일반, 공통으로 나뉘었던 주차장 구역을 없앤다.
  • 주차장 정보, 날짜, 시간, 주차가능대수 데이터를 저장할 수 있는 주차장 시간별 예약현황 테이블을 추가로 만든다.
  • 예약 전, 주차장 시간별 예약현황 테이블 의 주차가능대수를 확인하여 예약가능여부를 판단한다.
  • 예약 성공시, 주차장 시간별 예약현황 테이블 데이터를 업데이트한다.

Version 2

  • 사전예약


  • 즉시예약


  • 입차


  • 출차


  • 요금 계산


  • 설정
    • 주차장 내 일반, 예약, 공통구역은 따로 존재하지 않는다.
      • park_mgt_info 테이블의 zone 컬럼 삭제
    • 주차장별 날짜, 시간대에 따른 주차가능대수를 확인할 수 있는 주차장 시간별 예약현황 테이블이 존재한다.
      • park_booking_by_hour 테이블 생성
    • 예약은 사전예약, 즉시예약으로 나뉜다.
      • 일반차량이 입차 시도시 즉시예약처리 후 입차가 가능하다.
  • 사전 예약
    1. 예약시작시간이 종료시간보다 늦게 입력된 경우 예외처리
      • NOT_END_TO_START(400,"입차시간이 출차시간보다 빨라야 합니다.")
    2. 주차장 ID가 주차장 정보 DB에 없는 경우 예외처리
      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 로그인한 유저의 대표차량이 등록되지 않은 경우 예외처리
      • NOT_FOUND_CAR(400, "등록된 차량이 없습니다.")
    4. 예약시작~종료시간 사이에 동일차량으로 예약한 내역이 있는 경우 예외처리
      • ALREADY_RESERVED(400, "이미 예약된 시간입니다.")
    5. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    6. 예약시간이 주차장 운영시간을 벗어나는 경우 예외처리
      • NOT_OPEN_SELECTED_DATE(400, "선택하신 시간에는 운영하지 않습니다.")
    7. ParkBookingByHour 테이블에서예약 날짜, 시간에 해당하는 주차가능대수를 확인한다.
      • ParkBookingByHour 테이블에서 (주차가능대수 ≤ 0) 이라면, 예약불가 시간대 리스트(notAllowedTimeList)에 추가한다.
      • ParkBookingByHour 테이블에 예약날짜, 시간에 해당하는 데이터가 없다면, 그 시간대는 예약한 차량이 없는 것이므로 예약이 가능하다.
      • 예약불가 시간대가 하나도 없어야 예약 가능하다.
      • 예약불가 시간대가 하나 이상 있다면 예약 불가하므로 예외처리한다.
        • 예약불가 시간대를 Error 메시지로 출력한다.
    8. 예약정보를 생성하고, 시간별 주차현황 테이블(ParkBookingByHour) 정보를 업데이트한다.
      • ParkBookingByHour 에 예약시작시간 ~ 종료시간 사이 날짜, 시간에 해당하는 데이터가 있다면, 해당 데이터의 주차가능대수(available)를 1 줄인다.
      • 해당하는 데이터가 없다면, 날짜, 시간, 주차가능대수(= 총 구획 수 - 1)로 데이터를 생성하여 ParkBookingByHour 에 저장한다.
  • 즉시 예약
    1. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    2. 예약시간이 주차장 운영시간을 벗어나는 경우 예외처리
      • NOT_OPEN_SELECTED_DATE(400, "선택하신 시간에는 운영하지 않습니다.")
    3. ParkBookingByHour 테이블에서 예약 날짜, 시간에 해당하는 주차가능대수를 확인한다.
      • ParkBookingByHour 테이블에서 (주차가능대수 ≤ 0) 이라면, 예약불가 시간대 리스트(notAllowedTimeList)에 추가한다.
      • ParkBookingByHour 테이블에 예약날짜, 시간에 해당하는 데이터가 없다면, 그 시간대는 예약한 차량이 없는 것이므로 예약이 가능하다.
      • 예약불가 시간대가 하나도 없어야 예약 가능하다.
      • 예약불가 시간대가 하나 이상 있다면 예약 불가하므로 예외처리한다.
        • 예약불가 시간대를 Error 메시지로 출력한다.
    4. 예약정보를 생성하고, 시간별 주차현황 테이블(ParkBookingByHour) 정보를 업데이트한다.
      • 즉시예약인 경우, 비회원 예약이므로 예약정보 생성시 회원정보에는 Null 값이 들어간다.
      • ParkBookingByHour 에 예약시작시간 ~ 종료시간 사이 날짜, 시간에 해당하는 데이터가 있다면, 해당 데이터의 주차가능대수(available)를 1 줄인다.
      • 해당하는 데이터가 없다면, 날짜, 시간, 주차가능대수(= 총 구획 수 - 1)로 데이터를 생성하여 ParkBookingByHour 에 저장한다.
  • 입차
    1. 관리자 로그인한 아이디가 해당 주차장의 관리자가 아닌 경우 예외처리
      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 주차장 ID가 ParkInfo 에 없는 경우 예외처리
      • NOT_FOUND_PARK(400, "등록된 주차장이 없습니다.")
    3. 입차하려는 차량번호가 주차장에 이미 입차한 차량인 경우 예외처리
      • 주차현황DB(ParkMgtInfo)에서 해당 주차장에서 입차 차량번호로 입차한 차량 중, 마지막으로 입차한 현황 데이터를 가져온다.
      • 현황 데이터가 존재하고 출차정보가 없다면, 이미 입차된 차량이므로 예외처리한다.
      • ALREADY_ENTER_CAR(400, "이미 입차된 차량입니다.")
    4. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    5. 현재 입차시간 기준, 입차하려는 차량이 예약차량인지 확인한다.
      • 예약차량 : 예약정보 DB에서 주차장, 차량번호가 일치하면서, 예약 시작시간 ≤ 현재시간 ≤ 예약 종료시간 에 해당하는 데이터가 있는 경우
        • 예약정보를 가져온다.
      • 일반차량 : 예약차량이 아닌 경우 5-1. 입차시점 기준 한시간 이내에 예약된 내역이 있는지 확인한다.
        • 한시간 이내 예약된 내역이 있는 경우 → 예약시작시간을 입차시간으로 업데이트한다.
          • ParkBookingByHour 에 입차 시간대 주차가능자리(available)가 있는지 확인한다.
            • 입차 시간대 날짜, 시간에 해당하는 데이터가 없다면 ParkBookingByHour 에 새 데이터를 만들어준다.
            • 해당 데이터가 있고 (주차가능자리 수) > 0 이라면, 주차가능대수(available)를 1 줄인다.
            • 해당 데이터가 있고 (주차가능자리 수) <= 0 이라면, 주차장의 자리가 없으므로 예외처리한다.
              • NOT_PARKING_SPACE(400, "주차할 공간이 없습니다.")
          • 기존 예약내역의 시작 시간을 입차시간(현재)으로 업데이트한다.
        • 한시간 이내 예약된 내역이 없는 경우 → 즉시예약한다.
          • 해당 차량으로 입차시간 이후에 예약한 건이 있는지 확인한다.
            • 예약한 내역이 있고, 예약한 시간이 현재 주차하려는 시간과 겹친다면, 겹치는 시간을 Error 메시지로 출력한다.
            • 예약한 내역이 없거나, 예약 내역이 현재 주차하려는 시간과 겹치지 않는다면, 즉시예약 처리한다.
    6. 입차 시간대의 주차가능대수와 현재 주차중인 차량 수를 확인한다.
      • ParkBookinByHour 에서 (주차가능대수) < 0 이거나, (현재 주차중인 차량 수) >= (주차장 총 구획 수) 인 경우 입차불가하므로 예외처리한다.
        • NOT_PARKING_SPACE(400, "주차할 공간이 없습니다.")
      • (주차가능대수) >= 0 이고, (현재 주차중인 차량 수) < (주차장 총 구획 수) 라면, 입차 가능하다.
    7. 요금 계산 후 입차정보 생성하여 저장한다.
  • 출차
    1. 주차장 관리자 아이디의 주차장 ID와 사용자가 입차하는 주차장의 ID가 같지 않다면 예외처리
      • NOT_MGT_USER(400, "해당 주차장의 관리자가 아닙니다.")
    2. 출차하려는 차량이 주차장에 없는 경우 예외처리
      • NOT_FOUND_CAR_IN_PARK(400, "주차장에 차량이 없습니다.")
    3. 주차장 운영정보가 없는 경우 예외처리
      • NOT_FOUND_PARK_OPER_INFO(400, "해당 주차장 운영정보가 없습니다.")
    4. 요금을 계산한다.
      • 즉시예약 : 입차시간(예약시작시간) ~ 출차시간
      • 사전예약 예약시작시간 ~ 예약종료시간
    5. 출차시, 기존 시간별 예약현황에서 출차 후 시간대의 주차가능대수를 한 자리씩 늘린다.
      • 출차시간 ~ 예약종료시간 사이 시간의 ParkBookingByHour 시간대별 availble 숫자를 1 증가시킨다.
    6. 예약정보의 예약종료시간을 출차시간으로 업데이트한다.
  • 스케쥴링
    1. 매시간 0분마다 스케쥴링 실행
    2. 주차현황DB에서 예약종료시간이 지났으나 아직 주차중인 정보들을 가져온다.
    3. 2번에 해당하는 차량들의 예상출차시간(exitTime)을 1시간 더한다.
    4. 시간별 예약현황(ParkBookingByHour)에서 예약종료시간대에 해당하는 데이터를 업데이트한다.
      • 예약종료시간대의 데이터가 있다면, available 값을 1 줄인다.
      • 예약종료시간대의 데이터가 없다면, date, time, available(= 총 구획 수 - 1) 데이터를 생성하여 ParkBookingByHour에 저장한다.

Version 2 개선된 부분

  • 주차장 운영 효율성 확보
    • 주차장에 빈 자리가 있다면, 일반차량 입차가 가능하다.
    • 예약하려는 시간에 주차장 빈 자리가 있다면, 예약 가능하다.
  • 예약가능여부 확인 로직 성능 개선
    • 기존 매 시간마다 예약가능여부 확인 쿼리를 실행하던 로직에서, ParkBookingByHour 테이블의 주차가능대수(availbale)만 확인하면 되도록 수정하여 성능을 개선하였다.

Version 2 선택 이유

  • 예약차량 입차 안정성이 지켜지지 않는 일부 상황도 발생하지만, 대부분의 상황에서 입차 안정성이 보장된다.
  • 주차장 운영 효율성을 극대화할 수 있다.
  • 예약, 입차 로직 수행 속도 및 성능이 가장 많이 개선되었다.

Version 2 한계점

  • 예약차량 입차 안정성이 보장되지 않는 상황 발생
    • 주차장에 입차한 차량들이 예약종료시간을 넘어서도 출차하지 않은 경우, 다음 시간대 예약한 차량이 입차하지 못하는 상황이 발생할 수 있다.

한계점 극복

  • 차량들이 예약시간을 지키도록 서비스적 요소 추가
    • 예약시간 넘기는 경우 페널티 요금 부과

- 관리자페이지에서 예약시간 넘기는 차량 표시
    


ERD

  • Version0, Version 1

  • Version 1-1

  • Version 2

- parkBookingInfo 엔티티에 `exitTime`컬럼 추가

profile
기록을 남깁니다

0개의 댓글