Амазон
RRRRR - 54.158.198.97
@ Подписаться
Сотни бизнес-методик. Тысячи кейсов. Обновления.

сегодня 13803 Подписчиков


Обсуждения-аналоги

Скрыть / Показать Сортировать по дате
2016-02-03 15:59:07
Виталий Диденко » Всем
Добрый день, уважаемые участники форума!

Работая над разработкой мобильного приложения для Android и IOS, столкнулись с ситуацией, когда не понятно, какие данные нужно будет хранить в базе данных. Такая "неопределенность" не позволяет использовать обычные базы данных. Поэтому было принято решение использовать EAV модель хранения данных. На данном форуме была найдена модифицированная версия EAV базы данных. Она и была взята за основу.
 
Для хранения данных используется MySQL.
 
Данные которые нужно хранить в базе:
 
- пользователи;
- сведения о пользователях (имя, текущие координаты, контактная информация, программы установленные на мобильном);
- набор услуг которыми пользуется пользователь
- история использования услуг пользователя
- и ещё что-нибудь – для этого и взяли эту модель.
 
Структура таблиц:
 
Таблица «Sets ». Поля:
  • «Set_id» int(15); 
  • «Name_id» int(15); 
  • «Value_id» int(15).

Таблица «Values_string ». Поля:
  • «Value_id» int(15), AUTO_INCREMENT; 
  • «val »varchar(255), пустые значения ДА, значение по умолчению NULL.
 
Сейчас используется две таблицы, но для ускорения работы, нужно будет делить данные в нескольких таблицах.
 
Файл констант содержит:
  • $_phone_id = 1; $n_phone_id = "phone_id";
  • $_nik_name = 2; $n_nik_name = "nik_name";
  • $_name = 3; $n_name = "name";
  • $_fname = 4; $n_fname = "fname";
  • $_phone = 5; $n_phone = "phone";
  • $_programm = 10; $n_programm = "programm";
  • $_googl_id = 11; $n_googl_id = "googl_id";
  • $_my_catalog = 20; $n_my_catalog = "my_catalog";
  • $_catalog = 30;  $n_catalog = "catalog";
  • $_loc_x = 50; $n_loc_x = "loc_x";
  • $_loc_y = 51; $n_loc_y = "loc_y";
 
Этот файл нужен для понимания «кто есть кто». Так же он нужен для понимания в мобильном приложении – какое свойство вернулось со значением, а какое пустое.
 
Столкнулись с такой ситуацией, что при выборке данных не возвращаются данные, которых нет. Пример такой ситуации:
 
Если нужно выбрать в  базе всех пользователей, по которым нужно получить информацию:
  • phone_id, nik_name, phone, loc_x, loc_y, и в базе есть пользователи, которые не задали еще nik и phone
ожидается ответ вида:
  • {«00001», « Ваня», «78889995556», «30.34953», «40.23542»};
  • {«00002», «», «78889995556», «30.34963», «40.45542»};
  • {«00003», «Петя», «», «35.23453», «42.23232»}.
 
реальный ответ:
 
  • {«00001», « Ваня», «78889995556», «30.34953», «40.23542»};
  • {«00002», «77888454556», «30.34963», «40.45542»};
  • {«00003», «Петя», «35.23453», «42.23232»}.
 
Такой ответ неудобен для дальнейшей обработки т.к. не понятно «77888454556» это ник пользователя или телефон.
 
Поэтому добавили названия переменных:
 
$r1 = get (null, $_phone_id, null); //выбираем всех пользователей зарегистрированных в БД
 
while ($res1=mysql_fetch_array($r1)) //перебираем пользователей
{
 
    $_set_id = $res1["Set_id"];
    $properties = array($_phone_id,$_nik_name,$_phone,$_loc_x,$_loc_y); //эти свойства нужны нам
    $n_properties = array($n_phone_id,$n_nik_name,$n_phone,$n_loc_x,$n_loc_y);
     //это имена свойств
   
    foreach($properties as $index => $property)  //формируем массив с результатом
    {
        $r=get($_set_id,$property,null);
        while ($res=mysql_fetch_array($r))
            {
            $array_point [$n_properties[$index]] = $res["Val"];
            }
        }
        $array[]=$array_point;
    }
    OutResult($array);
 
Результат выборки:
  • {«phone_id:00001», «nik_name:Ваня», «phone :78889995556», «loc_x: 30.34953», «loc_y: 40.23542»};
  • {«phone_id:00002», «phone : 77888454556», «loc_x: 30.34963», «loc_y: 40.45542»};
  • {«phone_id:00003», «nik_name:Петя», «loc_x: 35.23453», «loc_y: 42.23232»}.
 
Данные результат удобен для дальнейшей обработке, так как понятно какие атрибуты получены.
 
Но все же это может быть «несовершенство» движка, но пока остановились на такой реализации.
 
Пока в движке реализованы следующие функции:
 
Получение данных:
 
   function get($Set_id, $Name, $Value) {
 
//1 Возвр. идентификатор наборов (Set_id), имеющих свойство Name со значением Value.
 
                   if($Set_id == null AND $Name != null AND $Value != null){
                       return get_Set_id($Set_id, $Name, $Value);
                   }
 
//2 Возвращает идентификатор наборов (Set_id), имеющих свойство Name.
 
                   if($Set_id == null AND $Name != null AND $Value == null){
                       return get_Value($Set_id, $Name, $Value);
                   }
 
//3 Возвращает значение свойства Name набора (Set) с идентификатором Set_id.
 
                   if($Set_id != null AND $Name != null AND $Value == null){
                       return get_all_Set_id($Set_id, $Name, $Value);
                   }
 
//4 Возвр. имя свойства со значением Value у набора (Set) с идентификатором Set_id.
 
                   if($Set_id != null AND $Name == null AND $Value != null){
                       return get_all_Names($Set_id, $Name, $Value);
                   }
 
//5 Возвр. все свойства набора с идентификатором Set_id.
 
                   if($Set_id != null AND $Name == null AND $Value == null){
                       return get_all_Name_id($Set_id, $Name, $Value);
                   }
   }
 
Добавление данных:
 
function add($Set_id, $Name, $Value)
 
   {
 
//добавление новой сущности
 
if($Set_id == null AND $Name != null AND $Value != null) {
 
                   $Set_id = get_SET_set_id();
 
                   $Value_id = get_VALUE_value_id($Value);
 
                   $query = "INSERT INTO sets (Set_id, Name_id, Value_id) VALUES ('".$Set_id."','".$Name."','".$Value_id."');";
 
                   $r = connect($query);
 
   }
 
//обновление значения
 
   if($Set_id != null AND $Name != null AND $Value != null) {
 
                   $Value_id = get_VALUE_value_id($Value);
 
                   $query = insert_or_update($Set_id, $Name, $Value_id);
 
                   print($query);
 
                   $r = connect($query);
 
   }
 
}
 
Будем признательны за отзывы и рекомендации по улучшению движка базы данных.
2016-02-04 14:50:27
Александр Сычёв » Виталий Диденко
Добрый день!

1. По поводу «данных, которых нет».

Эту проблему можно полностью решить на уровне пользовательского интерфейса. Если у некоторого типа наборов есть свойства, которые всегда должны быть, даже, если Пользователь не хочет их вводить, можно на уровне интерфейса задать им значение по умолчанию « » (пустая строка). Таким образом, у этих наборов всегда будет содержаться пустое свойство и вывод всегда будет следующего вида:

{«00001», «Ваня», «78889995556», «30.34953», «40.23542»};
{«00002», «», «78889995556», «30.34963», «40.45542»};
{«00003», «Петя»«», «35.23453», «42.23232»}.

2. По поводу получения всех свойств наборов.

Для чего в файле-справочнике записаны строковые имена? Ведь смысл файла-справочника именно в том, чтобы от них избавиться.

Вспомним еще раз, для чего нужны эти строковые имена. Они нужны для понимания ПРОГРАММИСТОМ И ТОЛЬКО ПРОГРАММИСТОМ того, с чем он работает. Ни пользователем, ни программой.

Поэтому давайте все таки уберем их из справочника и оставим так:

$_phone_id = 1; 
$_nik_name = 2; 
$_name = 3; 
$_fname = 4; 
$_phone = 5; 
$_programm = 10; 
$_googl_id = 11; 
$_my_catalog = 20; 
$_catalog = 30;  
$_loc_x = 50; 
$_loc_y = 51; 

и модифицируем код следующим образом:

Во-первых, переименуем массив:

$properties = array($_phone_id,$_nik_name,$_phone,$_loc_x,$_loc_y)

следующим образом:

$names = array($_phone_id,$_nik_name,$_phone,$_loc_x,$_loc_y)

Ведь в нём, всё-таки, хранятся не свойства как таковые, а только их имена. На первый взгляд, это кажется незначительным и неважным изменением, но через некоторое время Вы увидите, насколько это упрощает понимание того, с чем мы работаем.

Во-вторых, поменяем само получение свойств:

 foreach($names as $index => $name)  //формируем массив с результатом
    {
        $r=get($_set_id, $name, null);
        while ($res=mysql_fetch_array($r))
            {
            $set[$name] = $res["Val"];
            }
    }
    OutResult($set);

Замечание: непонятная переменная $array здесь заменена на более понятную $set, опять-таки, из соображений читаемости.

Результатом будет массив с ключами, соответствующими именам свойств вида:

{[1]=>«00001», [2]=> « Ваня», [5]=> «78889995556», [50]=> «30.34953», [51]=> «40.23542»};


Теперь, если мы захотим получить некоторое конкретное свойство из этого массива, мы просто сделаем следующее:

$wanted_value = $set[$_phone];

Согласитесь, что, вопреки не вполне читаемой, на первый взгляд, структуре массива, нам вполне понятно, что мы только что из него достали.

Таким образом, в соответствующих полях можно легко отобразить данные, которые там необходимы с помощью чего-то вроде этого:

<form method="post" name="visualizwer">

                       <?
                                 $texts = array(”ID телефона”,“Ник” ,”Номер”,”Широта”,”Долгота”);
                                 foreach($names as $index => $name){
                                         echo(
                                                    "<span>
                                                              <input
                                                               id =\"$any_id\"
                                                               name =\"$name \"
                                                               class =\"element text\"
                                                               placeholder = \"$texts[$index] \"
                                                               value =\"$set[$name]\"
                                                               type =\"text\"
                                                               size=\"60\">
                                                     </span>"
                                         );
                                         echo ("is selected $any_id.<br /><br />");
                              }
                        ?>

Обратите внимание, что читаемые для человека названия свойств вводятся ЗА ШАГ ДО ИХ ОТОБРАЖЕНИЯ НА ЭКРАН, не раньше. Более того, здесь они понимаются не как «имена свойств», а как «указания для Пользователей». Они с таким же успехом могли быть следующего вида:

$texts = array(”Ваш уникальный АйДи”,“Ваш невероятный никнейм” ,”Ваш телефон”,”Ваша Широта”,”Ваша долгота”);

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

3. По поводу добавления данных

Не совсем понятно, почему настолько разнятся алгоритмы для добавления и обновления данных. Ведь, когда мы обновляем данные, мы пишем их в указанную строчку, а когда добавляем, то сначала создаем строчку, а затем пишем данные в указанную строчку. Логика для этих двух случаев отличается лишь на одну операцию – генерацию нового ID.

4. По поводу функции GET

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

В нашем "ядре" этим составителем является функция get_brick («кирпичик»). Она будет принимать на вход следующие параметры:

get_brick ($selects, $table, $where_keys, $where_values);

$selects - говорит нам: что мы должны выбрать;
$table – говорит нам: откуда выбирать;
$where_keys – говорит нам: какие ключи проверять у наших значений;
$where_values – говорит нам: какие значения должны быть у соответствующих ключей.

Имея такую функцию, мы можем просто менять передаваемые ей параметры, в зависимости от того, что мы хотим найти, а она уже составит нам запрос, к примеру вида:

SELECT VALUE_ID,VAL FROM VALUES_STRING WHERE VAL IN ('Дима');

Возвращаемый такой функцией результат мы уже потом раскладываем в читаемый для человека вид.

С Уважением, 

2016-03-13 15:32:08
Редакция » Всем
Уважаемые Коллеги!

Обращаем Ваше внимание: схожее обсуждение идёт также и в соседней "ветке".

Спасибо,
Уважаемые Коллеги!

Если Вам нравится наш Форум, Вы можете поддержать его, отправив любую сумму (тогда выберите опцию "Спасибо за Форум").

Вы также можете поддержать конкретное обсуждение и получить гарантированный ответ от наших специалистов (тогда выберите опцию "Прошу эксперта ответить в этой теме").
Задайте Ваш вопрос здесь.

Большое Спасибо!


Яндекс.Метрика