Введение
Информационный блок, являющийся частью базы данных (строка данных). В информатике запись (также называемая структурой, структурой или составными данными) является базовой структурой данных. Записи в базе данных или электронной таблице обычно называются "строками". Запись — это набор полей, возможно, различных типов данных, как правило, в фиксированном количестве и последовательности. Поля записи также могут называться членами, особенно в объектно-ориентированном программировании; поля также могут называться элементами, хотя это может привести к путанице с элементами коллекции. Например, дата может храниться в виде записи, содержащей числовое поле года, поле месяца, представленное в виде строки, и числовое поле дня месяца. В записях о персонале могут быть указаны имя, зарплата и должность. Запись круга может содержать центр и радиус — в этом случае центр может быть представлен как запись точки, содержащая координаты x и y. Записи отличаются от массивов тем, что их количество полей определяется в определении записи, и тем, что записи являются гетерогенным типом данных; не все поля должны содержать один и тот же тип данных. Тип записи — это тип данных, который описывает такие значения и переменные. Большинство современных компьютерных языков позволяют программисту определять новые типы записей. Определение включает в себя указание типа данных каждого поля и идентификатора (имени или метки), с помощью которого можно получить доступ к нему. В теории типов, произведения (без названий полей) обычно предпочтительнее из-за их простоты, но корректные типы записей изучаются в языках, таких как System F sub. Поскольку теоретические записи типов могут содержать поля с функциями первого класса в дополнение к данным, они могут выражать многие особенности объектно-ориентированного программирования. Записи могут существовать на любом носителе, включая оперативную память и устройства массового хранения, такие как магнитные ленты или жесткие диски. Записи являются фундаментальным компонентом большинства структур данных, особенно связанных структур данных. Многие компьютерные файлы организованы как массивы логических записей, часто сгруппированных в более крупные физические записи или блоки для повышения эффективности. Параметры функции или процедуры часто можно рассматривать как поля переменной записи; а аргументы, переданные этой функции, можно рассматривать как значение записи, которое присваивается этой переменной во время вызова. Кроме того, в стеке вызовов, который часто используется для реализации вызовов процедур, каждая запись является записью активации или кадром вызова, содержащей параметры процедуры и локальные переменные, адрес возврата и другие внутренние поля. Объект в объектно-ориентированном языке — это, по сути, запись, которая содержит процедуры, специализированные на обработке этой записи; а типы объектов — это развитие типов записей. Действительно, в большинстве объектно-ориентированных языков записи являются специальными случаями объектов и известны как простые старые структуры данных (PODS), в отличие от объектов, использующих возможности ООП. Запись можно рассматривать как компьютерный аналог математического кортежа, хотя кортеж может или не может считаться записью, и наоборот, в зависимости от соглашений и конкретного языка программирования. В том же духе, тип записи можно рассматривать как компьютерный аналог декартова произведения двух или более математических множеств, или реализацию абстрактного типа произведения в конкретном языке.
In computer science, a record (also called a structure, struct, or compound data) is a basic data structure. Records in a database or spreadsheet are usually called "rows". A record is a collection of fields, possibly of different data types, typically in a fixed number and sequence. The fields of a record may also be called members, particularly in object oriented programming; fields may also be called elements, though this risks confusion with the elements of a collection. For example, a date could be stored as a record containing a numeric year field, a month field represented as a string, and a numeric day of month field. A personnel record might contain a name, a salary, and a rank. A Circle record might contain a center and a radius—in this instance, the center itself might be represented as a point record containing x and y coordinates. Records are distinguished from arrays by the fact that their number of fields is determined in the definition of the record, and by the fact the records are a heterogenous data type; not all of the fields must contain the same type of data. A record type is a data type that describes such values and variables. Most modern computer languages allow the programmer to define new record types. The definition includes specifying the data type of each field and an identifier (name or label) by which it can be accessed. In type theory, product types (with no field names) are generally preferred due to their simplicity, but proper record types are studied in languages such as System F sub. Since type theoretical records may contain first class function typed fields in addition to data, they can express many features of object oriented programming. Records can exist in any storage medium, including main memory and mass storage devices such as magnetic tapes or hard disks. Records are a fundamental component of most data structures, especially linked data structures. Many computer files are organized as arrays of logical records, often grouped into larger physical records or blocks for efficiency. The parameters of a function or procedure can often be viewed as the fields of a record variable; and the arguments passed to that function can be viewed as a record value that gets assigned to that variable at the time of the call. Also, in the call stack that is often used to implement procedure calls, each entry is an activation record or call frame, containing the procedure parameters and local variables, the return address, and other internal fields. An object in object oriented language is essentially a record that contains procedures specialized to handle that record; and object types are an elaboration of record types. Indeed, in most object oriented languages, records are just special cases of objects, and are known as plain old data structures (PODSs), to contrast with objects that use OO features. A record can be viewed as the computer analog of a mathematical tuple, although a tuple may or may not be considered a record, and vice versa, depending on conventions and the specific programming language. In the same vein, a record type can be viewed as the computer language analog of the Cartesian product of two or more mathematical sets, or the implementation of an abstract product type in a specific language.
Ключи
Запись может иметь ноль или более ключей. Ключ сопоставляет выражение со значением или набором значений в записи. Первичный ключ уникален во всех хранимых записях; существует только один такой ключ. Иными словами, для любого первичного ключа не может быть дубликатов. Например, файл сотрудника может содержать номер сотрудника, имя, отдел и зарплату. Номер сотрудника будет уникальным в организации и являться первичным ключом. В зависимости от носителя информации и организации файла, номер сотрудника может быть проиндексирован – то есть также храниться в отдельном файле для ускорения поиска. Код отдела не обязательно уникален; он также может быть проиндексирован, в этом случае он будет считаться вторичным или альтернативным ключом. Если он не проиндексирован, для получения списка всех сотрудников в определенном отделе потребуется сканировать весь файл сотрудников. Ключи обычно выбирают таким образом, чтобы минимизировать вероятность сопоставления одного ключа с несколькими значениями. Например, поле зарплаты обычно не рассматривается как подходящее для использования в качестве ключа, поскольку многие сотрудники, вероятно, будут получать одинаковую зарплату. Индексирование – один из факторов, которые учитываются при проектировании файла.
История
Понятие записи можно проследить до различных типов таблиц и книг, используемых в бухгалтерском учете с давних времен. Современное представление о записях в информатике, с полями четко определенного типа и размера, уже присутствовало в механических калькуляторах XIX века, таких как Аналитическая машина Бэббиджа. Первоначально машиночитаемым носителем для данных (в отличие от управляющей информации) была перфокарта, использовавшаяся для записей в переписи населения США 1890 года: каждая перфокарта представляла собой одну запись. Сравните хозяйственную запись 1880 года и перфокарту 1895 года. Записи широко использовались в первой половине XX века, когда большая часть обработки данных осуществлялась с помощью перфокарт. Обычно каждая запись файла данных записывалась на одной перфокарте, при этом конкретным полям соответствовали определенные столбцы. Как правило, запись была наименьшей единицей информации, которую можно было считать из внешнего устройства хранения (например, считывателя карт, магнитной ленты или диска). Содержимое записей, оформленных как перфокарты, изначально называли «записями единичной длины», поскольку перфокарты имели заранее заданную длину документа. С развитием систем хранения данных с использованием жестких дисков и магнитной ленты стандартными стали записи переменной длины. Запись переменной длины – это запись, размер которой в байтах приблизительно равен сумме размеров ее полей. Это было невозможно реализовать до создания более совершенного оборудования для хранения, поскольку все перфокарты должны были соответствовать заранее определенным длинам документов, которые мог прочитать компьютер, так как в то время карты физически подавались в машину. Большинство языков машинных команд и ранних ассемблеров не имели специального синтаксиса для записей, однако эта концепция была доступна (и широко использовалась) посредством индексных регистров, косвенной адресации и самомодифицирующегося кода. Некоторые ранние компьютеры, такие как IBM 1620, имели аппаратную поддержку для выделения записей и полей, а также специальные инструкции для копирования таких записей. Концепция записей и полей играла центральную роль в некоторых ранних утилитах сортировки и табулирования файлов, таких как Report Program Generator (RPG) от IBM. COBOL был первым широко распространенным языком программирования, поддерживающим типы записей, и его средства определения записей были в то время весьма сложными. Язык позволяет определять вложенные записи с буквенно-цифровыми, целочисленными и дробными полями произвольного размера и точности, а также поля, которые автоматически форматируют любое присвоенное им значение (например, добавление знаков валюты, десятичных точек и разделителей групп цифр). Каждый файл связан с переменной записи, в которую данные считываются или записываются. COBOL также предоставляет оператор MOVE CORRESPONDING, который присваивает соответствующие поля двух записей в соответствии с их именами. Ранние языки, разработанные для численных вычислений, такие как FORTRAN (до FORTRAN IV) и Algol 60, не поддерживали типы записей; однако более поздние версии этих языков, такие как FORTRAN 77 и Algol 68, добавили такую поддержку. Оригинальный язык программирования Lisp также не имел записей (за исключением встроенной ячейки cons), но его S-выражения предоставляли адекватную замену. Язык программирования Pascal был одним из первых языков, полностью интегрировавших типы записей с другими базовыми типами в логически согласованную систему типов. Язык программирования PL/I обеспечивал поддержку записей в стиле COBOL. Язык программирования C изначально предоставлял концепцию записи в виде своеобразного шаблона (структуры), который можно было наложить на область памяти, а не истинного типа данных записи. Позднее они были предоставлены (с помощью объявления typedef), но эти две концепции по-прежнему различны в языке. Большинство языков, разработанных после Pascal (таких как Ada, Modula и Java), также поддерживают записи. Хотя записи больше не часто используются в своем первоначальном контексте (то есть исключительно для хранения данных), они оказали влияние на новые объектно-ориентированные языки программирования и реляционные системы управления базами данных. Поскольку записи обеспечивают большую модульность в способе хранения и обработки данных, они лучше подходят для представления сложных концепций реального мира, чем примитивные типы данных, предоставляемые по умолчанию в языках. Это повлияло на более поздние языки, такие как C++, Python, JavaScript и Objective-C, которые решают те же проблемы модульности, что и программисты. Объекты в этих языках по сути являются записями с добавлением методов и наследования, которые позволяют программистам управлять поведением данных, а не только их содержимым. Многие программисты считают записи устаревшими, поскольку объектно-ориентированные языки обладают функциями, значительно превосходящими возможности записей. С другой стороны, многие программисты утверждают, что малый объем накладных расходов и возможность использования записей в ассемблере делают их по-прежнему актуальными при программировании на низком уровне абстракции. Сегодня наиболее популярные языки в индексе TIOBE, который является индикатором популярности языков программирования, в той или иной степени испытали влияние записей из-за того, что они являются объектно-ориентированными. Языки запросов, такие как SQL и Object Query Language, также испытали влияние концепции записей. Эти языки позволяют программисту хранить наборы данных, которые по сути являются записями, в таблицах. Затем эти данные можно извлечь с помощью первичного ключа. Сами таблицы также являются записями, которые могут иметь внешний ключ: ключ, ссылающийся на данные в другой таблице.
Призначение и сравнение
Большинство языков позволяют присваивать записи, имеющие точно такой же тип записи (включая одинаковые типы и имена полей в одном и том же порядке). Однако, в зависимости от языка, два независимо определенных типа данных записей могут рассматриваться как различные типы, даже если они имеют одинаковый набор полей. Некоторые языки также могут разрешать присваивание между записями, поля которых имеют разные имена, сопоставляя каждое значение поля с соответствующей переменной поля по их позициям в записи; например, комплексное число с полями "real" и "imag" может быть присвоено переменной записи, представляющей 2D-точку с полями X и Y. В этом случае оба операнда по-прежнему должны иметь одинаковую последовательность типов полей. Некоторые языки также могут требовать, чтобы соответствующие типы имели одинаковый размер и кодировку, чтобы всю запись можно было присвоить как неинтерпретированную битовую строку. Другие языки могут быть более гибкими и требовать только, чтобы каждое поле значения могло быть корректно присвоено соответствующему полю переменной; например, короткое целое число может быть присвоено длинному целому числу или наоборот. Другие языки (например, COBOL) могут сопоставлять поля и значения по их именам, а не по позициям. Те же возможности применимы и к сравнению двух значений записей на равенство. Некоторые языки также могут допускать сравнение по порядку ("<" и ">"), используя лексикографический порядок, основанный на сравнении отдельных полей. PL/I допускает оба предыдущих типа присваивания, а также позволяет использовать структурные выражения, такие как a = a+1, где "a" – запись, или структура в терминологии PL/I.
Выбор распределительного поля Algol 68
В Algol 68, если Pts был массивом записей, каждая из которых содержала целочисленные поля X и Y, можно было записать Y из Pts, чтобы получить массив целых чисел, состоящий из полей Y всех элементов Pts. Следовательно, выражения Y из Pts[3] := 7 и (Y из Pts)[3] := 7 имели бы одинаковый эффект.
Заявление Паскаля "с"
В языке программирования Паскаль команда с R do S выполняет последовательность команд S так, как если бы все поля записи R были объявлены как переменные. Подобно переходу в другое пространство имен в объектно-ориентированном языке, таком как C#, для доступа к полям больше не требуется использовать имя записи в качестве префикса. Таким образом, вместо записи "Пт. X := 5; Пт. Y := Пт. X + 3" можно написать .
Представление в памяти
Представление записей в памяти различается в зависимости от языков программирования. Как правило, поля хранятся в памяти последовательно, в том же порядке, в котором они объявлены в типе записи. Это может привести к тому, что два или более полей будут храниться в одном слове памяти; эта возможность часто используется в системном программировании для доступа к отдельным битам слова. С другой стороны, большинство компиляторов добавляют поля-заполнители, обычно невидимые для программиста, чтобы соответствовать требованиям к выравниванию, предъявляемым машиной, например, требованию, чтобы поле с плавающей точкой занимало одно слово. Некоторые языки могут реализовывать запись как массив адресов, указывающих на поля (и, возможно, на их имена и/или типы). Объекты в объектно-ориентированных языках часто реализуются более сложным образом, особенно в языках, поддерживающих множественное наследование.
Самоопределяемые записи
Самоопределяющаяся запись — это тип записи, который содержит информацию для идентификации типа записи и поиска информации внутри неё. Она может содержать смещения элементов, благодаря чему сами элементы могут храниться в любом порядке или быть опущены. Информация, хранящаяся в самоопределяющейсяся записи, может рассматриваться как метаданные для этой записи, аналогичные тем, что можно найти в метаданных UNIX для файла, включая такую информацию, как время создания записи и её размер в байтах. Альтернативно, различные элементы записи, каждый из которых имеет свой идентификатор, могут просто следовать друг за другом в произвольном порядке.