Как было сказано выше, другой способ получить аутентификационный синтаксический анализатор представления IPv6 - использовать программирование. Вот тот, который полностью соответствует RFC-4291 и RFC-5952. Я написал этот код в ANSI C (работает с GCC, прошел тесты в Linux - работает с clang, прошел тесты на FreeBSD). Таким образом, он полагается только на стандартную библиотеку ANSI C, поэтому ее можно скомпилировать повсюду (я использовал ее для разбора IPv6 внутри модуля ядра с помощью FreeBSD).
// IPv6 textual representation validating parser fully compliant with RFC-4291 and RFC-5952
// BSD-licensed / Copyright 2015-2017 Alexandre Fenyo
#include <string.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
typedef enum { false, true } bool;
static const char hexdigits[] = "0123456789abcdef";
static int digit2int(const char digit) {
return strchr(hexdigits, digit) - hexdigits;
}
// This IPv6 address parser handles any valid textual representation according to RFC-4291 and RFC-5952.
// Other representations will return -1.
//
// note that str input parameter has been modified when the function call returns
//
// parse_ipv6(char *str, struct in6_addr *retaddr)
// parse textual representation of IPv6 addresses
// str: input arg
// retaddr: output arg
int parse_ipv6(char *str, struct in6_addr *retaddr) {
bool compressed_field_found = false;
unsigned char *_retaddr = (unsigned char *) retaddr;
char *_str = str;
char *delim;
bzero((void *) retaddr, sizeof(struct in6_addr));
if (!strlen(str) || strchr(str, ':') == NULL || (str[0] == ':' && str[1] != ':') ||
(strlen(str) >= 2 && str[strlen(str) - 1] == ':' && str[strlen(str) - 2] != ':')) return -1;
// convert transitional to standard textual representation
if (strchr(str, '.')) {
int ipv4bytes[4];
char *curp = strrchr(str, ':');
if (curp == NULL) return -1;
char *_curp = ++curp;
int i;
for (i = 0; i < 4; i++) {
char *nextsep = strchr(_curp, '.');
if (_curp[0] == '0' || (i < 3 && nextsep == NULL) || (i == 3 && nextsep != NULL)) return -1;
if (nextsep != NULL) *nextsep = 0;
int j;
for (j = 0; j < strlen(_curp); j++) if (_curp[j] < '0' || _curp[j] > '9') return -1;
if (strlen(_curp) > 3) return -1;
const long val = strtol(_curp, NULL, 10);
if (val < 0 || val > 255) return -1;
ipv4bytes[i] = val;
_curp = nextsep + 1;
}
sprintf(curp, "%x%02x:%x%02x", ipv4bytes[0], ipv4bytes[1], ipv4bytes[2], ipv4bytes[3]);
}
// parse standard textual representation
do {
if ((delim = strchr(_str, ':')) == _str || (delim == NULL && !strlen(_str))) {
if (delim == str) _str++;
else if (delim == NULL) return 0;
else {
if (compressed_field_found == true) return -1;
if (delim == str + strlen(str) - 1 && _retaddr != (unsigned char *) (retaddr + 1)) return 0;
compressed_field_found = true;
_str++;
int cnt = 0;
char *__str;
for (__str = _str; *__str; ) if (*(__str++) == ':') cnt++;
unsigned char *__retaddr = - 2 * ++cnt + (unsigned char *) (retaddr + 1);
if (__retaddr <= _retaddr) return -1;
_retaddr = __retaddr;
}
} else {
char hexnum[4] = "0000";
if (delim == NULL) delim = str + strlen(str);
if (delim - _str > 4) return -1;
int i;
for (i = 0; i < delim - _str; i++)
if (!isxdigit(_str[i])) return -1;
else hexnum[4 - (delim - _str) + i] = tolower(_str[i]);
_str = delim + 1;
*(_retaddr++) = (digit2int(hexnum[0]) << 4) + digit2int(hexnum[1]);
*(_retaddr++) = (digit2int(hexnum[2]) << 4) + digit2int(hexnum[3]);
}
} while (_str < str + strlen(str));
return 0;
}
Я пошел бы со вторым.
Student
-------
StudentID
Name
MentorID
мне нравится, имеют название таблицы в Первичном ключе, но это не должно быть на каждом поле. Также MentorID был бы то, как я назову внешний ключ также (предполагающий, что Наставник является названием таблицы, на которую он указывает).
Этот путь поле MentorID в таблице Student имеет то же имя как поле MentorID в таблице Mentor. Некоторым людям не нравится он, потому что это может немного сбивать с толку при присоединении к таблицам, но я предпочитаю явно называть таблицы полей в соединениях так или иначе,
Я на самом деле как:
Student
-------
Id
Name
IdMentor
Я предполагаю это вид Венгерской записи имитаторов. Существует также больше визуального различия между IdMentor
и Mentor.Id
, чем между MentorId
и Mentor.Id
.
Я предпочитаю использовать этот шаблон:
student
-------
id
name
mentor_id
_id for foreign keys
Нет никакого "правильного" ответа для этого. Просто выберите любое соглашение о присвоении имен, которое Вы любите (и все другие, кто будет использовать Ваш дб), и придерживайтесь его. Существует много хорошо разработанных соглашений о присвоении имен в Интернете. Просто ищите Google на "соглашениях о присвоении имен SQL".
, По моему опыту, люди используют полностью различные стили, но это в порядке, пока целое приложение (или все проекты в той же организации) использует те же конвенции.
Имя вероятно зарезервированное слово, я никогда не использовал бы его в качестве имени столбца. И при этом я никогда не рассматривал бы имена хранения в одном поле. Вам действительно нужны first_name, Middle_name, last_name, Суффикс (для III, Младший, и т.д.). Рассмотрите то, что необходимо сделать для запросов поля имени, когда Вы хотите всех клиентов по имени 'Smith'.
я также никогда не называл бы идентификационное поле ID. Я предпочитаю, чтобы мои идентификационные поля имели то же имя во всех дочерних таблицах, как оно делает намного легче видеть то, о чем Вы говорите особенно, когда у Вас есть сложный запрос involing много различных идентификаторов.
только один человек может когда-либо служить наставником? Unikely. Наставник должен быть отдельной таблицей и должна быть присоединяющаяся таблица с StudentID и mentorID
Я обычно делаю номер 3
Student-------
ID
Name
MentorID
И я пошел бы почти с третьим:
Student
-------
Id
Name
Mentor_Id
SELECT Student.Name,
Student_Mentor.Name
FROM Student
INNER JOIN Mentor AS Student_Mentor ON Student.Mentor_Id = Student_Mentor.Id
Я мог бы использование StudentName вместо Имени, потому что это сделает соединения легче. Часто я нахожу, что у меня есть многие, много таблиц со столбцом "имени" и "описания".
Так, как я ненавижу его, я пошел бы с Опцией 1:
Student
-------
StudentID
StudentName
MentorID
причина этого при присоединении к другим таблицам со столбцом "Name" скажите Курс или Градус, или что-то, присоединение требует, чтобы Вы переименовали столбцы для предотвращения неоднозначных имен. Контакт с длинными именами, которые имеют имя таблицы в нем, является раздражающим, но это может сохранить Вас работа над длительным периодом.
Я предпочитаю первый.
Путем предоставления полям более собственного имени, чем всего Id
или Name
, легче видеть, что Вы присоединяетесь правильно, и Вы не должны использовать псевдонимы для полей при выборе полей больше чем из одной таблицы:
select s.StudentId, s.StudentName, m.MentorId, m.MentorName
from Student s
inner join Mentor m on m.MentorId = s.MentorId
по сравнению с
select s.Id as StudentId, s.Name as StudentName, m.Id as MentorId, m.Name as MentorName
from Student s
inner join Mentor m on m.Id = s.MentorId
кроме того, Word Name
является зарезервированным словом в некоторых базах данных (например, SQL Server), таким образом, это не всегда практично для использования в качестве имени поля.
Я предпочитаю второй:
Students
-------
StudentID
Name
MentorID
, Где:
ID
на конце columnname. EndDate
, BeginDate
для дат. Я предпочитаю последний так, чтобы соединение между таблицами было похоже:
SELECT blah blah blah
FROM Student INNER JOIN Mentor
ON Student.MentorID = Mentor.ID
, Но это почти столь же субъективно как "Вам нравится Camel-регистр?": P
главное должен быть последовательным. Я должен был иметь дело с прошлым с некоторыми базами данных, где они никогда не могли выбирать стандарт. Таким образом в некоторых таблицах PK был бы StudentID, другие идентификатор других и Student_ID. Или они последовательно не использовались имя при использовании в качестве внешних ключей. Oy, я начинаю разглагольствовать...
Я лично пошел бы с:
Students
--------
student_id
first_name
last_name
mentor_id
я предпочитаю использовать подчеркивания, потому что исследования показали, что они улучшают удобочитаемость кода очень по сравнению с горбатой нотацией.
я могу также понять аргументы в пользу того, чтобы просто использовать "идентификатор", а не "student_id", таким образом, я не против этого.
начиная с некоторого sql прописного материала средств форматирования я иду с follwing:
student
-------
id
name
mentor_id
тот путь я могу сохранить разделение слова в дб.
в коде OO я использую соответствующие имена Camel-регистра
воспитанный, getMentorId ()
Начиная с регулярного RDBMS являются довольно иерархическими, DBMS содержит базу данных - база данных содержит таблицу - таблица содержит столбец - столбец содержит значение, мне не нравится повторяющееся использование имен таблиц в именах столбцов.
Мой голос переходит в:
Student
--------
id (pk)
name
mentor (fk) (alt. mentorId)
довольно легко выбрать корректные поля, и в случае соединений между таблицами я часто переименовываю имена столбцов, т.е.:
SELECT s.id AS StudentID, s.name AS StudentName, m.id AS MentorId, m.name AS MentorName
FROM Studens AS s
INNER JOIN Mentors AS m ON m.id=s.mentor