Search
Write a publication
Pull to refresh
0
0
Send message

Если имелось ввиду про хранение, то все намного проще, int остается полноценным. Признак что в поле нет данных (Null) хранится в битовой маске перед самой записью. Таким образом если в записи есть Null, то само значение не записывается хранилище, но взводится флаг. Строка с Null занимает меньше памяти чем запись в которой записан 0 (битовая маска есть всегда). А еще извлечение подобных записей происходит быстрее, так как они более плотно упакованы на страницу, так что совет не использовать Null весьма спорный.

Один из примеров что были у меня - ведомости на начисление/удержание, все по заветам денормализации dPeriod (период расчета) и idCharge (Код оплаты) вынесены в Blt (Шапку ведомости)

Bltlist - содержит список сотрудников с суммами. Следующий запрос собирает информацию сколько сотрудник получил по указанному коду оплат в текущем расчетном периоде


```sql

select *

from

Blt

inner join Bltlist on

Blt.Id = BltList.IdBlt

where

Blt.dPeriod = '01.01.2024' and

Blt.idCharge = 10 and

Bltlist.idCard = 1000

```


PG читает из Bltlist по индексу idCard все записи с самих лохматых времен. Затем собирает все ведомости по индексу dPeriod, idCharge опять же все, в том числе где нашего сотрудника нет. затем делает хешджоин так как что слева что справа записей более 1000.


А теперь если делаем денормализацию и дублируем поля dPeriod, idCharge в Bltlist


```sql

select *

from

Blt

inner join Bltlist on

Blt.Id = BltList.IdBlt

where

Bltlist.dPeriod = '01.01.2024' and

Bltlist.idCharge = 10 and

Bltlist.idCard = 1000

```


Теперь PG по индексу dPeriod, idCharge, idCard читает только те записи, которые нам нужны ни каких лишних чтений

Мое понимание такое - В первом варианте сначала читается индекс и затем по каждой записи идет в основную таблицу. так как порядок записей совпадает, то страница не вытесняется из кеша и просто читается повторно из оперативной памяти.
Во втором случае все начинается так же, но так как сортировка индекса не совпадает с сортировкой в таблице, то происходит постоянный промах, а старые страницы вытесняются из кеша. В худшем случае приходится прочитать страницу данных для каждой записи + полный индекс.

Можно обратное число записывать, и в этом случае наоборот искать минимальное

В своем проекте сделал так, преобразование делается в набор | и пробелов, потом в отчетной системе или веб странички у строки делается межсимвольный интервал таким что бы две || соприкасались. Как итог не нужно было ни каких внешних библиотек все возвращала СУБД. Единственное ограничение в том что ограничен в высоте штрих кода.
Как то давно для своих проектов использовал такие макросы
#define digitalWriteC(pin,val)\
 if (val) { *((volatile uint8_t *) port_to_output_PGM[digital_pin_to_port_PGM[pin]]) |= (digital_pin_to_bit_mask_PGM[pin]);}\
 else {*((volatile uint8_t *) port_to_output_PGM[digital_pin_to_port_PGM[pin]]) &= ~(digital_pin_to_bit_mask_PGM[pin]);}

#define pinModeC(pin,mode)\
  if (mode == INPUT) { \
    *((volatile uint8_t *) port_to_mode_PGM[digital_pin_to_port_PGM[pin]]) &= ~(digital_pin_to_bit_mask_PGM[pin]);\
    *((volatile uint8_t *) port_to_output_PGM[digital_pin_to_port_PGM[pin]]) &= ~(digital_pin_to_bit_mask_PGM[pin]);\
  } else if (mode == INPUT_PULLUP) {\
    *((volatile uint8_t *) port_to_mode_PGM[digital_pin_to_port_PGM[pin]]) &= ~(digital_pin_to_bit_mask_PGM[pin]);\
    *((volatile uint8_t *) port_to_output_PGM[digital_pin_to_port_PGM[pin]]) |= (digital_pin_to_bit_mask_PGM[pin]);\
  } else {\
    *((volatile uint8_t *) port_to_mode_PGM[digital_pin_to_port_PGM[pin]]) |= (digital_pin_to_bit_mask_PGM[pin]);\
  };

inline uint8_t digitalReadC (uint8_t pin) __attribute__((always_inline));
uint8_t digitalReadC (uint8_t pin)
 {
   if (*((volatile uint8_t *) port_to_input_PGM[digital_pin_to_port_PGM[pin]]) & (digital_pin_to_bit_mask_PGM[pin])) {return HIGH;} else {return LOW;};  
 };


Работают корректно только если номера пинов и портов — константы. GCC всегда транслирует в sbi и cbi если это возможно. При этом Изменений в программе минимум. Всего то нужно использовать digitalWriteC вместо digitalWrite.

Information

Rating
Does not participate
Registered
Activity